首页 > 其他分享 >(33/60)K次取反后最大化的数组和、加油站、分发糖果

(33/60)K次取反后最大化的数组和、加油站、分发糖果

时间:2024-03-01 23:11:22浏览次数:32  
标签:ratings 遍历 nums 33 复杂度 取反 60 int

K次取反后最大化的数组和

leetcode:1005. K 次取反后最大化的数组和

贪心法

思路

两次贪心:(每次取反k--)

  1. 排序,一次遍历,按绝对值从大到小地把负数取反。
  2. 如果K次取反没用完,再排序一次,反复取反最小元素。

(或者一开始就按绝对值从大到小排序,只需排序一次)

复杂度分析

时间复杂度:O(NlogN)。

空间复杂度:O(1)。

注意点

  1. sort排序规则函数可以通过声明一个普通函数的方式来写。

    // 比较函数,用于比较两个整数的大小
    bool compareInt(int a, int b) {
        return a < b; // 从小到大排序
    }
    
    int main() {
        std::vector<int> numbers = {3, 1, 4, 1, 5, 9};
        
        // 使用自定义的比较函数进行排序
        std::sort(numbers.begin(), numbers.end(), compareInt);
        
        for (int num : numbers) {
            std::cout << num << " ";
        }
        return 0;
    }
    

代码实现

初次实现:

class Solution {
public:
    // 排序,一次遍历,按绝对值从大到小地把负数取反
    // 如果K次取反没用完,再排序一次,反复取反最小元素
    int largestSumAfterKNegations(vector<int>& nums, int k) {
        sort(nums.begin(),nums.end());
        if(nums[0] < 0){    // 如果没有负数,跳过这步
            for(int i = 0;i < nums.size() && k > 0;i++){
                if(nums[i] < 0){
                    nums[i] = -nums[i];
                    k--;
                }
            }
        }
        if(k > 0){
            sort(nums.begin(),nums.end());
            while(k > 0){
                nums[0] = -nums[0];
                k--;
            }
        }
        int result = 0;
        for(int i : nums) result += i;

        return result;
    }
};

优化版:(其实都差不多)

class Solution {
static bool cmp(int a,int b){
    return abs(a) > abs(b); // 按绝对值从大到小排序
}
public:
    int largestSumAfterKNegations(vector<int>& nums, int k) {
        sort(nums.begin(),nums.end(),cmp);
        for(int i = 0;i < nums.size() && k > 0;i++){
            if(nums[i] < 0){
                nums[i] *= -1;
                k--;
            }
        }
        while(k > 0){
            nums[nums.size() - 1] *= -1;
            k--;
        }
        int result = 0;
        for(int num:nums) result += num;
        
        return result;
    }
};

加油站

leetcode:134. 加油站

贪心法

思路

遍历一遍,计算当前油量(从开始点到当前点的累计油量),一旦为负,则移动开始点到i+1,油量归零,从i+1为开始点重新累计(油量为负肯定过不去)。一轮遍历过后,总油量如果为负数,那无论如何都过不去;如果不为负,那么当前的开始节点即为可通过的开始点。

复杂度分析

时间复杂度:O(N)。

空间复杂度:O(1)。

注意点

代码实现

class Solution {
public:
    // 类似股票题,如果净入油量为负,一开始肯定走不过去,把它排在最后面。
    // 遍历每个站,计算净入油量,如果为负就从下一个点开始
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        int curSum = 0;  // 净入
        int total = 0;  // 总油量
        int start = 0;
        for(int i = 0;i < gas.size();i++){
            curSum += gas[i] - cost[i];
            total += gas[i] - cost[i];
            if(curSum < 0){
                start = i + 1;
                curSum = 0;
            }
        }
        // 如果整体为负,那无论如何都过不去
        if(total < 0) return -1;    
        return start;
    }
};

分发糖果

leetcode:135. 分发糖果

第二道hard,Σ(っ °Д °;)っ

贪心法

思路

每次只处理一边,分两次处理。

创建糖果数组,默认每人为1

从左往右遍历一次,若右边比左边大,右边等于左边加1

从右往左遍历一次,若左边比右边大,左边等于右边加1和原值取最大

复杂度分析

时间复杂度:O(N)。

空间复杂度:O(N)。

注意点

代码实现

class Solution {
public:
    // 默认每人为1
    // 从左往右遍历一次,若右边比左边大,右边等于左边加1
    // 从右往左遍历一次,若左边比右边大,左边等于右边加1和原值取最大
    int candy(vector<int>& ratings) {
        int total = 0;
        vector<int> candies(ratings.size(),1);
        for(int i = 1;i < ratings.size();i++){
            if(ratings[i - 1] < ratings[i]) candies[i] = candies[i - 1] + 1;
        }
        for(int i = ratings.size()-2;i >= 0;i--){
            if(ratings[i] > ratings[i + 1]) candies[i] = max(candies[i + 1] + 1,candies[i]);
        }
        for(int i : candies) total += i;
        
        return total;
    }
};

标签:ratings,遍历,nums,33,复杂度,取反,60,int
From: https://www.cnblogs.com/tazdingo/p/18048152

相关文章

  • 常用日期和时间标准对比:HTML, ISO 8601, RFC 3339, RFC 5322
    1.HTML,ISO8601,RFC3339,RFC5322对比日期和时间,对于不同系统和平台之间的数据交换和互操作至关重要。本文将对比HTML标准、ISO8601、RFC3339和RFC5322,为读者提供参考。表格文字版见文末-附1.1.标准链接HTML标准:https://html.spec.whatwg.org/multipage......
  • ABC338G 题解
    ABC338G题解计数题,没有太多思维难度,就是麻烦。显然+和*是比较难搞的,应考虑子问题。复杂度要求线性,考虑每个位置的贡献。Case1:只有数字Ex:1234考虑2的贡献,枚举一下看看。\(12=1\times10+2\times1\)\(123=1\times100+2\times10+3\times1\)\(1234=\dots\)\(2=2......
  • SC5360B丨9.05至9.55 GHz X波段双通道RF下变频器
    产品简介频率范围:9.05GHz至9.55GHz,信号带宽40MHz,噪声系数典型值为4.8dB更多信息请加weixin-pt890111获取 SC5360B是一款9.05至9.55GHz双通道双级转换超外差下变频器,集成了本地振荡器(LO),可提供卓越的性能。初设计用于EW,它可以满足X波段雷达系统,通信系统,光谱监测系统和频......
  • SP Devices ADQ1600-1.6 GSPS,14位RF数字化仪
    产品简介:♦单通道,14比特分辨率,1.6GSPS采样率♦800MHz模拟输入带宽及500MSamples板载内存♦适用于例如IF/RF采样及高速数据记录等不同的应用场合更多信息请加weixin-pt890111获取产品信息分辨率:14位输入信号范围:2.2Vpp输入通道:1触发:软件/扩展/级别时钟:整数/分机(SMA)外部......
  • 高速数字化仪-ADQ33-12bit 1GSPS采样率 OCT
    产品简介:♦2通道,12bit分辨率,1GSPS采样率♦1GHz模拟带宽及8GB内存♦直流耦合♦OCT专用数字化仪更多信息请加weixin-pt890111获取产品优势 紧凑的高性能数字化仪,可优化系统解决方案实时处理和高数据吞吐量 ADQ33支持高达7Gbyte/s的持续流传输到GPU和CPU。通过开放式F......
  • 高速数字化仪-M5i.33xx-x16系列
    产品简介:高精度、高采样率、高带宽;单通道6.4GS/s双通道3.2GS/s,精度12bit,带宽2GHz,DC耦合,可变量程;PCIex16Gen3.0。产品简述  高性能的M5i.33xx系列高速数据采集卡,提供了结合高精度、高采样率、高带宽和业内最快流盘速度的数字化仪指标。 一个高速采集系统可以选择6.4GS......
  • 代码随想录算法训练营第三十三天 | 135. 分发糖果, 134. 加油站, 1005.K次取反后最大化
      1005.K次取反后最大化的数组和 已解答简单 相关标签相关企业 给你一个整数数组 nums 和一个整数 k ,按以下方法修改该数组:选择某个下标 i 并将 nums[i] 替换为 -nums[i] 。重复这个过程恰好 k 次。可以多次选择同一个下......
  • 我的闲鱼Python爬虫接单总结和经验,最高600元一单
    最近,我在闲鱼上利用Python爬虫技术接了一些任务,想必你一定好奇,通过这样的方式,到底能不能挣钱,能挣多少钱?今天我就来分享一下我的经验和总结。一、接单经历之前Vue的作者尤大在微博上说被动收入是最能带来自由的东西,这个时代的程序员其实在创造被动收入上有天然优势,然而大......
  • 代码随想录算法训练营第三十三天| ● 1005.K次取反后最大化的数组和 ● 134. 加油站
    K次取反后最大化的数组和 题目链接:1005.K次取反后最大化的数组和-力扣(LeetCode)思路:首先增序排序,然后依次将负值取反,如果负数先用完,则再排序一次,将最小的正数取反之后求和;如果k先用完,直接求和。注意sort默认是增序排序,若想要要降序,则不能使用sort(nums.end(),nums.begin())......
  • 国产芯片方案:充气泵方案SIC8833C芯片
    车载手持充气泵是一个用在汽车、摩托车、电动车车胎打气,也常用于充气篮球、足球等球类补气用。在很多时候都是作为车载设备使用,通常用于车胎气压不够,爆胎修理补气使用,这种手持的充气泵,体积小,携带方便,几乎有车的人手一个。车载手持充气泵方案设计主要根据其工作原理,以传感......