记一次动态规划和贪心的刷题经历

给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个下标。
示例 1:
输入:nums = [2,3,1,1,4]
输出:true
解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。
作者:力扣 (LeetCode)
链接:https://leetcode-cn.com/leetbook/read/top-interview-questions-medium/xvb8zs/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

如何理解动态规划和贪心的解题思路?

**TODO...

动态规划

dp数组维护第i位可以进行的最远跳数。

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

每次使用dp数组只和前一位元素交互,所以不需要一个数组,只需维护前一位元素作为一个变量即可。但注意,优化只是优化了使用逻辑,动态规划还是把每步的最优解存储了下来供下一步利用。

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

贪心

只维护一个表示当前能达到的最远距离的全局变量,通过不断遍历数组更新这个值。

public boolean canJump(int[] nums) {
        if(nums.length == 1){
            return true;
        }
        int preJump = nums[0]; //当前能跳的的最远下标
        for(int i = 1; i < nums.length; i++){
            if(preJump < i){
                return false; //最远下标达不到当前下标
            }
            preJump = Math.max(nums[i] + i, preJump);
            if(preJump >= nums.length - 1){ //更新最远下标
                return true;
            }
        }
        return false; 
    }
posted @ 2021-11-11 15:01  芝芝与梅梅  阅读(33)  评论(0)    收藏  举报