leetcode-跳跃游戏

369 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

下个月要参加一个比赛,想来还是在动态规划的题目上可以再多联系一些,所以在leetcode找到了相关题集,每天做一些,希望下个月的比赛能带领队友走向胜利而不是团灭吧。

题目

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

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

示例 2:
输入:nums = [3,2,1,0,4]
输出:false
解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 , 所以永远不可能到达最后一个下标。

思路

前两天刚做过一题差不多的。 题目要求的是,能否达到最后一个目标,我们顺着考虑,就是从当前位置出发,可以到达哪些位置,把这些位置标记为可达,然后从可达的位置出发,可能达到哪些新位置,如果所有的可达位置都遍历完成后,不能包含最后一点点,那就是不可达,如果包含,那就是可达。当然,在遍历的过程中发现已经包含了最后一个点,那也不用再傻傻遍历完。 模拟一下示例1:我们初始在下标0的位置,目前可达的点只有0,它的值是2,这样我们的可达点就是[0,2],因为0已经遍历过了,我们接下来遍历1和2,遍历1之后,可达2、3、4,已经包含4,所以肯定是可达的。

Java版本代码

class Solution {
    public boolean canJump(int[] nums) {
        int len = nums.length;
        int index = 0;
        int start = index + 1;
        int end = index + nums[0];
        while (end < len - 1) {
            if (end < start) {
                break;
            }
            int max = end;
            for (int i = start; i <= end; i++) {
                if (i + nums[i] > max) {
                    max = i + nums[i];
                }
            }
            // start 更新成下一次开始遍历的点,因为0-end已经遍历过了,下一次要遍历的点至少是end+1
            start = end + 1;
            // end 更新成下一次能跳到的最远的点
            end = max;
        }
        if (end >= len - 1) {
            return true;
        } else {
            return false;
        }
    }
}