LeetCode Day32 122&55&45

88 阅读1分钟

摸不准啥时候用贪心,Carl哥总结的贪心思路:贪心的本质是选择每一阶段的局部最优,从而达到全局最优。如果找到局部最优,然后推出整体最优,那么就是贪心。 所以贪心本质是局部最优推出全局最优。但仔细观察贪心的题貌似dp又都能解决...

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

这里可以选择第一天买入股票,第二天就把股票卖出,假如是正收益,那么我们就获得了一个局部最优值,负收益的话不计入即可。这道题用贪心思想做反而会比用dp简单的多。

class Solution {
    public int maxProfit(int[] prices) {
        int result = 0;
        for(int i = 1; i < prices.length; i ++){
            result += Math.max(0, prices[i] - prices[i - 1]);
        }

        return result;
    }
}
55. 跳跃游戏

这题主要并不在于跳跃过程中应该选择跳几步,而是只需要思考所给选择的跳跃步数是否能把整个数组都跳完。也就是说跳跃的覆盖范围是否能比数组长度大,如果可以就能直接返回true了。每次移动取最大跳跃步数(得到最大的覆盖范围),每移动一个单位,就更新最大覆盖范围。贪心算法局部最优解:每次取最大跳跃步数(取最大覆盖范围),整体最优解:最后得到整体最大覆盖范围,看是否能到终点

class Solution {
    public boolean canJump(int[] nums) {
        if(nums.length == 1) return true;

        int coverLength = 0;
        for(int i = 0; i <= coverLength; i ++){
        //这里注意用i+num[i]而不是num[i]的原因是,每次可跳跃的范围是在当前我所站在的格子位置+格子所在的数组给我的范围。
            coverLength = Math.max(coverLength, i+nums[i]);
            if(coverLength >= nums.length - 1){
                return true;
            }
        }
        return false;
    }
}
45. 跳跃游戏 II

理解本题的关键在于:以最小的步数增加最大的覆盖范围,直到覆盖范围覆盖了终点,这个范围内最小步数一定可以跳到,不用管具体是怎么跳的,不纠结于一步究竟跳一个单位还是两个单位。

class Solution {
    public int jump(int[] nums) {
        int res = 0;
        int temp = 0;
        int end = 0;
        for(int i = 0; i <= end && end < nums.length - 1; i ++){
            temp = Math.max(temp, i + nums[i]);
            if(i == end){
                end = temp;
                res ++;
            }
        }

        return res;
    }
}