代码随想录第三十四天|Leetcode1005.K次取反后最大化的数组和、Leetcode134. 加油站、Leetcode135. 分发糖果

代码随想录第三十四天|Leetcode1005.K次取反后最大化的数组和、Leetcode134. 加油站、Leetcode135. 分发糖果

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

题目链接:Leetcode1005.K次取反后最大化的数组和
熟悉熟悉这个sort函数自定义排序方法的用法

class Solution {
    
    
private:
    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();i++){
    
    
            if(nums[i]<0 && k>0){
    
    
                nums[i]*=-1;
                k--;
            }
        }
        int sum=0;
        if(k%2==1) nums[nums.size()-1]*=-1;
        for(int num:nums) sum+=num;
        return sum;
    }
};

Leetcode134. 加油站

题目链接:Leetcode134. 加油站
本来不想动脑了,先整个双for循环暴力解试试,又遇到了力扣的暴力杀手用例,被拿下了。
答案给了个很巧妙的方法:

  1. 如果gas的总和小于cost总和,那么无论从哪里出发,一定是跑不了一圈的
  2. rest[i] = gas[i]-cost[i]为一天剩下的油,i从0开始计算累加到最后一站,如果累加没有出现负数,说明从0出发,油就没有断过,那么0就是起点。
  3. 如果累加的最小值是负数,汽车就要从非0节点出发,从后向前,看哪个节点能把这个负数填平,能把这个负数填平的节点就是出发节点。
class Solution {
    
    
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
    
    
        int curSum = 0;
        int min = INT_MAX; // 从起点出发,油箱里的油量最小值
        for (int i = 0; i < gas.size(); i++) {
    
    
            int rest = gas[i] - cost[i];
            curSum += rest;
            if (curSum < min) {
    
    
                min = curSum;
            }
        }
        if (curSum < 0) return -1;  // 情况1
        if (min >= 0) return 0;     // 情况2
                                    // 情况3↓
        for (int i = gas.size() - 1; i >= 0; i--) {
    
    
            int rest = gas[i] - cost[i];
            min += rest;
            if (min >= 0) {
    
    
                return i;
            }
        }
        return -1;
    }
};

还有个非常nb的方法,这个思路真的牛逼:i从0开始累加rest[i],和记为curSum,一旦curSum小于零,说明[0, i]区间都不能作为起始位置,因为这个区间选择任何一个位置作为起点,到i这里都会断油,那么起始位置从i+1算起,再从0计算curSum

class Solution {
    
    
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
    
    
        int curSum = 0;
        int totalSum = 0;
        int start = 0;
        for (int i = 0; i < gas.size(); i++) {
    
    
            curSum += gas[i] - cost[i];
            totalSum += gas[i] - cost[i];
            if (curSum < 0) {
    
       // 当前累加rest[i]和 curSum一旦小于0
                start = i + 1;  // 起始位置更新为i+1
                curSum = 0;     // curSum从0开始
            }
        }
        if (totalSum < 0) return -1; // 说明怎么走都不可能跑一圈了
        return start;
    }
};

Leetcode135. 分发糖果

离独立做出困难题最近的一次,一定要二刷

二刷提醒

最核心的易错点有三个:

  1. 不要想着同时考虑两边,左大于右,右大于左,分开考虑。
  2. 对下一个进行判断时要记得用上上一个值,比如123,判断23时要用上12的判断结果
  3. 倒着判断时,要记得是max,因为之前已经赋值过一次了,要判断当前值和前值加一哪个更大
class Solution {
    
    
public:
    int candy(vector<int>& ratings) {
    
    
        vector<int> nums(ratings.size(),1);
        //右>左
        for(int i=1;i<ratings.size();i++){
    
    
            if(ratings[i]>ratings[i-1]) nums[i]=nums[i-1]+1;
        }
        //左>右
        for(int i=ratings.size()-2;i>=0;i--){
    
    
            if(ratings[i]>ratings[i+1]) nums[i]=max(nums[i],nums[i+1]+1);
        }
        int result=0;
        for(int i=0;i<nums.size();i++){
    
    
            result+=nums[i];
        }
        return result;
    }
};

猜你喜欢

转载自blog.csdn.net/muzi_taibai/article/details/129350516
今日推荐