代码随想录算法训练营第二十八天|贪心算法part2

122.买卖股票的最佳时机II

题目链接:122. 买卖股票的最佳时机 II - 力扣(LeetCode)

文章讲解:代码随想录

思路:

这道题的思路很巧妙最终利润是可以分解的 

假如第 0 天买入,第 3 天卖出,那么利润为:prices[3] - prices[0]。

相当于(prices[3] - prices[2]) + (prices[2] - prices[1]) + (prices[1] - prices[0])。

此时就是把利润分解为每天为单位的维度,而不是从 0 天到第 3 天整体去考虑!

所以做差后收集正值就可以了

class Solution {
public:
    int maxProfit(vector& prices) {
        int result=0;
        for(int i=0;i0){
                result+=diff;
            }
        }
        return result;
        
    }
};

55. 跳跃游戏

题目链接:55. 跳跃游戏 - 力扣(LeetCode)

文章讲解:代码随想录

思路:跳不过去的坎是0 我本来想收集所有0的下标 然后判断每一个带0的下标是否可以跳过去

难点在于难以判断每一个0能否跳过去

代码随想录思路:

用覆盖范围去求解 每遍历一个单位 更新全局覆盖范围

class Solution {
public:
    bool canJump(vector& nums) {   
        int index=0;
        for(int i=0;iindex){
                    index=i+nums[i];             //更新最大范围
                } 
            }      
        }
        return true;   
    }
};

 

45.跳跃游戏II

题目链接:45. 跳跃游戏 II - 力扣(LeetCode)

文章讲解:代码随想录

思路:

class Solution {
public:
    int jump1(vector& nums,int n){
        if(n==0)return 0;
        vectortemp;
        for(int i=n-1;i>=0;i--){
            if(i+nums[i]>=n){
                temp.push_back(i);
            }
        }
        int ans=INT_MAX;
        for(auto x:temp){
            int j=jump1(nums,x);
            if(j& nums) {
        return jump1(nums,nums.size()-1);
    }
};

 递归做法 时间复杂度太高 超出时间限制

贪心策略:仍然从最大覆盖范围考虑,一旦下标到达最大覆盖范围 且还没有到达终点 就需要多加一步

错误解答:

class Solution {
public:
    int jump(vector& nums) {
        int curDis=0;
        int result=0;
        int n=nums.size()-1;
        for(int i=0;i=n){break;}
        }
        return result;
    }
};

这里错误的地方在于更新最大覆盖范围总是用当前元素的值去更新 事实上最大覆盖范围可能是之前元素的值

所以引入

 int nextDistance = 0;   // 下一步覆盖最远距离下标

 正确解答:

class Solution {
public:
    int jump(vector& nums) {
        int curDis=0;
        int result=0;
        int n=nums.size()-1;
         int nextDistance = 0;   // 下一步覆盖最远距离下标
        for(int i=0;i=n){break;}
        }
        return result;
    }
};

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

题目链接:1005. K 次取反后最大化的数组和 - 力扣(LeetCode)

文章讲解:代码随想录

 思路:

按照从小到大顺序排序 让第一个元素取反 重复k次

然后求值

缺点:时间复杂度为knlogn

class Solution {
public:
    int largestSumAfterKNegations(vector& nums, int k) {
        while(k){
            sort(nums.begin(),nums.end());
            nums[0]=-nums[0];
            k--;
        }
        int sum=0;
        for(auto x:nums){
            sum+=x;
        }
        return sum;
    }

};

代码随想录解法:

  • 第一步:将数组按照绝对值大小从大到小排序,注意要按照绝对值的大小
  • 第二步:从前向后遍历,遇到负数将其变为正数,同时K--
  • 第三步:如果K还大于0,那么反复转变数值最小的元素,将K用完
  • 第四步:求和

你可能感兴趣的:(贪心算法,算法)