贪心算法part2

贪心算法part2

122. 买卖股票的最佳时机 II - 力扣(LeetCode)

画折线图,发现收集全部的上升曲线,就可以取得最大利润

贪心的想法是分解利润

比如第0天买入,第3天卖出,那么利润就是prices[3] - prices[0]

分解后就是(prices[3] - prices[2]) + (prices[2] - prices[1]) + (prices[1] - prices[0])

局部最优: 收集每天的正利润

全局最优: 求得最大利润

class Solution {
    public int maxProfit(int[] prices) {
        int res = 0;
        for(int i = 0; i < prices.length - 1; i++){
            if(prices[i + 1] > prices[i]){
                res += (prices[i + 1] - prices[i]);
            }
        }
        return res;
    }
}

55. 跳跃游戏 - 力扣(LeetCode)

时间复杂度为O(n),遍历求能够跳跃的覆盖范围就可以了

贪心体现:每次跳跃取最大覆盖范围

class Solution {
    public boolean canJump(int[] nums) {
        if(nums.length == 0){
            return false;
        }
        int cover = 0;
        for(int i = 0; i < nums.length; i++){
            if(cover >= nums.length - 1){
                return true;
            }
            if(cover < i){
                return false;
            }
            cover = Math.max(cover, nums[i] + i);
        }
        return false;
    }
}

45. 跳跃游戏 II - 力扣(LeetCode)

做了好久

跟上面的跳跃游戏相似,但是要统计跳跃的次数,所以以跳跃后的节点,做for循环,看循环中节点的cover范围,如果范围到了,就返回res次数

本题贪心的体现很好想

class Solution {
    public int jump(int[] nums) {
        if(nums.length == 1 || nums[0] == 0){
            return 0;
        }
        int res = 1;  //默认已经跳了一步,因为for循环中将cover跳出条件放在最前面,当cover更新到覆盖数据范围时,还没跳出最后一步
        int cover = nums[0];  //同上
        int index = 0;
        for(int i = 0; i < nums.length;){
            if(cover >= nums.length - 1){
                return res;
            }
            for(int j = i; j <= nums[i] + i; j++){  //从当前节点开始跳,更新最大的cover
                if(nums[j] + j >= cover){
                    cover = nums[j] + j;
                    index = j;
                }
            }
            i = Math.max(index, i + 1);
            res++;
        }
        return res;
    }
}

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

自己的思路是k次循环,每次sort排序,将最小值取反,然后nums做和

但是比较慢

class Solution {
    public int largestSumAfterKNegations(int[] nums, int k) {
        for(int i = 0; i < k; i++){
            Arrays.sort(nums);
            nums[0] = -nums[0];
        }
        int res = 0;
        for(int i = 0; i < nums.length; i++){
            res += nums[i];
        }
        return res;
    }
}

如果优化就是先处理负数,然后根据剩下需要处理的数量的奇偶来处理,这样肯定比我的做法快

posted @ 2025-06-21 21:51  泡芙猪  阅读(22)  评论(0)    收藏  举报