LeetCode55、跳跃游戏(dp或者贪心)

题目描述

https://leetcode-cn.com/problems/jump-game/
在这里插入图片描述

解法

思考使用dp来做的话,我们的dp数组定义为什么?

  • 变量是什么?每步跳跃,抵达的位置不同,每个位置能跳的步数也不同,我们如何定义dp?
  • 很明显我们用dp来表达每个位置能跳的步数,所以我们只能选择抵达的位置,于是得出dp[i]表示从0到i下标是否可以抵达
  • 思考递推,当前的dp[i]取决于之前的从之前的位置出发是否能抵达,我们需要维护一个变量来表示当前能抵达的最大下标,如果当前的下标在最大能抵达下标范围内(因为可以跳1步),则为true,于是更新max
  • 边界就是dp[0] = true;
  • 编写代码
class Solution {
    
    
    public boolean canJump(int[] nums) {
    
    
        boolean []dp = new boolean[nums.length];//表示从0到下标i的是否可以到达

        dp[0]=true;
        int max = 0+nums[0];//当前能抵达的最大下标
        for(int i=1;i<nums.length;i++){
    
    
            if(max>=i){
    
    
                dp[i] = true;
                if(nums[i]+i>max)
                    max = nums[i]+i;//更新能抵达的最大下标
            }
            //else dp[i] = false;//不能抵达
        }
        return dp[nums.length-1];

    }
}

在这里插入图片描述
根据dp使用,可以优化空间复杂度:

class Solution {
    
    
    public boolean canJump(int[] nums) {
    
    
        //boolean []dp = new boolean[nums.length];//表示从0到下标i的是否可以到达

        boolean res = true;//dp[0]等于true
        int max = 0+nums[0];//当前能抵达的最大下标
        for(int i=1;i<nums.length;i++){
    
    
            if(max>=i){
    
    
                res = true;
                if(nums[i]+i>max)
                    max = nums[i]+i;//更新能抵达的最大下标
            }else
                res = false;
        }
        return res;
    }
}

如果使用贪心算法呢?

转化问题:请问通过题目中的跳跃规则,最多能跳多远?如果能够越过最后一格,返回 true,否则返回 false。
于是我们可以写出如下贪心代码:

	int n = nums.length;
    int farthest = 0;
    for (int i = 0; i < n - 1; i++) {
    
    
        // 不断计算能跳到的最远距离
        farthest = max(farthest, i + nums[i]);
        // 可能碰到了 0,卡住跳不动了
        if (farthest <= i) return false;
    }
    return farthest >= n - 1;

发现和上面的代码差不多,我们是否可以思考以下贪心和动态规划的区别呢?

猜你喜欢

转载自blog.csdn.net/qq_44861675/article/details/114580625
今日推荐