Leetcode-55-跳跃游戏(贪心、动态规划)

一、题目

给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个位置。

示例 1:
输入: [2,3,1,1,4]
输出: true
解释: 我们可以先跳 1 步,从位置 0 到达 位置 1, 然后再从位置 1 跳 3 步到达最后一个位置。

https://leetcode-cn.com/problems/jump-game/

二、解题思路

整体思路

1、能否到达最后一个位置
--> 最多能跳多远,如果能跳过最后一个,则为true
2、最值问题
--> 动态规划/贪心

关键问题:最多能跳多远?

贪心
不是顺着值计算去跳跃。
思路1:每一步都计算一下从当前位置最远能够跳到哪里,如果能跳到最后一个位置处就为true。实现见题解1
问题2:会出现badcase1 eg [0,2,3]的情况,即有0处被跳过了,应该为false,最后错误输出了true
思路2: 再加上对0的处理,如果不能往后面跳(max==i),则输出false。实现见题解2
问题2: eg [3,0,8,2,0,0,1] 在0处跳出了,其实可以不走0处,跳到后面然后可以有解,所以应该输出为true,错误输出了true

eg [0]也需要注意

正确思路:
设置一个全局最优的最远位置 farthest 做对比,通过每一步的最优解,更新全局最优解,这就是贪心。
1、如果某一个作为 起跳点 的格子可以跳跃的距离是 3,那么表示后面 3 个格子都可以作为 起跳点。
2、可以对每一个能作为 起跳点 的格子都尝试跳一次,把 能跳到最远的距离 不断更新。
3、如果可以一直跳到最后,就成功了。
(很难想到啊emmmmmm)

三、题解

暴力解法

题解1:

Java题解

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

[0,2,3]

题解2

Java题解

// badcase
// [0]
// [3,0,8,2,0,0,1]
class Solution {
    public boolean canJump(int[] nums) {
        if (nums.length == 0 || nums.length == 1) {
            return true;
        }
        int max_step = 0, len = nums.length;
        for (int i = 0; i < len - 1; i++) {
            max_step = i + nums[i];
            if (max_step >= (len - 1)) {
                return true;
            }
            if (max_step == i) {
                return false;
            }
        }
        return false;
    }
}
badcase2
image.png
题解3

Java题解
错误解答

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

错误案例

输入:[2,5,0,0]
输出:false
预期结果:true

正确题解
注意for循环的n-1,遍历的是起跳点

class Solution {
    public boolean canJump(int[] nums) {
        if (nums.length == 0 || nums.length == 1) {
            return true;
        }
        int max_step = 0, len = nums.length;
        for (int i = 0; i < len - 1; i++) {
            max_step = Math.max(i + nums[i], max_step);         //
            if (max_step >= (len - 1)) {
                return true;
            }
            if (max_step == i) {
                return false;
            }
        }
        return false;
    }
}
结果
执行用时:2 ms, 在所有 Java 提交中击败了79.34%的用户
内存消耗:42.1 MB, 在所有 Java 提交中击败了9.80%的用户
复杂度分析

时间复杂度:O(n),遍历一遍数组
空间复杂度:O(1)

四、测试数据

1、[2,5,0,0] true
2、[0] true
n==1
3、[2, 0, 0] true
--> n-1

参考

1、题解参考
2、优秀题解
https://leetcode-cn.com/problems/jump-game/solution/55-by-ikaruga/

你可能感兴趣的:(Leetcode-55-跳跃游戏(贪心、动态规划))