随想录训练营Day32 | 贪心 122.买卖股票的最佳时机II, 55. 跳跃游戏, 45.跳跃游戏II

78 阅读1分钟

随想录训练营Day32 | 贪心 122.买卖股票的最佳时机II, 55. 跳跃游戏, 45.跳跃游戏II

标签: LeetCode闯关记


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

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

time: 6min

55. 跳跃游戏

key: 其实跳几步无所谓,关键在于可跳的覆盖范围! 不一定非要明确一次究竟跳几步,每次取最大的跳跃步数,这个就是可以跳跃的覆盖范围。 问题转化: 跳跃覆盖范围究竟可不可以覆盖到终点! 贪心算法局部最优解:每次取最大跳跃步数(取最大覆盖范围),整体最优解:最后得到整体最大覆盖范围,看是否能到终点。

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

time : 40min

反思: 尝试用树结构+回溯暴力遍历

public class Solution {
    public boolean canJump(int[] nums) {
        return canJump(nums, 0);
    }
    
    private boolean canJump(int[] nums, int pos) {
        if (pos == nums.length - 1) {
            // 如果当前位置达到了终点,则返回 true
            return true;
        }
        
        int maxStep = Math.min(pos + nums[pos], nums.length - 1);
        for (int i = pos + 1; i <= maxStep; i++) {
            if (canJump(nums, i)) {
                // 如果在当前位置可以跳到最后一个位置,则返回 true
                return true;
            }
        }
        
        // 如果在当前位置无法跳到最后一个位置,则返回 false
        return false;
    }
}
  • 时间复杂度非常高,为 O(2^n),其中 n 是数组中元素的个数。
  • 使用了递归的方式来遍历所有可能的情况。在每个位置上,会有至多 nums[i] 种不同的跳跃方案,

45.跳跃游戏II

key:

class Solution {
    public int jump(int[] nums) {
        //注意特殊情况
        if(nums == null || nums.length == 0 || nums.length == 1 ){
            return 0;
        }
        int count = 0;
        int curRange = nums[0];
        int nextRange = 0;
        int nextMaxRange = 0;
        for (int i = 0; i <= curRange; i++) {
            nextRange = nums[i] + i;
            if(curRange < nums.length - 1){
                nextMaxRange = Math.max(nextMaxRange, nextRange);
                if(i == curRange){
                    curRange = nextMaxRange;
                    count++;
                }
            }else {
                count++;
                break;
            }
        }
        return count;
    }
}

time: 1h30min (细节把我绕晕)