08— 跳跃游戏【LeetCode55】

吃猫的鱼
2023-07-16 / 0 评论 / 52 阅读 / 正在检测是否收录...

题目

55. 跳跃游戏 - 力扣(LeetCode)

给定一个非负整数数组 nums ,你最初位于数组的 第一个下标

数组中的每个元素代表你在该位置可以跳跃的最大长度。

判断你是否能够到达最后一个下标。

示例一:

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

示例二:

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

解题

解法一

思路

看到本题,我的第一个想法是进行遍历,然后新建一个数组arrive[]记录当前的格子是否能够到达,默认是0,arrive[0]初始的值为1(起点),要是arrive数组中值为 1的话就表示该格可以到达。

用一个指针i遍历nums[i]进行模拟前进情况,遍历到的arrive[i]要是为0,表示当前位置无法到达,跳过本次循环,i继续往前;

arrive[i]要是为1,就开始从当前i处开始进行模拟前进,找到当前i位置可以到达的地方,并且标注arrive[i]值为1i继续往前。

最后看arrive[nums.length]是否是到达的状态即可返回结果。

解决

class Solution {
    public boolean canJump(int[] nums) {
        int length = nums.length;
        //首先定义一个数组用来存储每个格子能否到达的情况
        int[] arrive = new int[length];
        //首先默认第一个地方是可以到达的
        arrive[0]=1;
        //开始遍历数组
        for(int i=0;i<length;i++){
            if(nums[i]==0){
                //首先判断当前位置nums是不是0,要是0,直接跳过当前位置
                continue;
            }else if(arrive[i]!=1){
                //判断当前位置是否可以到达,不可以到达直接跳过
                continue;
            }else{
                //站在轮到的位置,开始遍历看当前指针所在的格子能够到达的情况
                for(int j=0;j<=nums[i];j++){
                    //首先判断是否越界问题
                    if((i+j)<=(length-1)){
                        //将能够到达的位置赋为1
                        arrive[i+j]=1;
                    }else{
                        //越界,跳出当前指针所在的到达情况循环
                        break;
                    }
                }
            }
        }
        //直接判断arrive数组最后一个位置是否为可达状态即可返回答案
        if(arrive[length-1]==1) return true;
        return false;
    }
}

结果

> 2023/07/16 15:06:06    
解答成功:
    执行耗时:469 ms,击败了5.06% 的Java用户
    内存消耗:42.9 MB,击败了19.14% 的Java用户

哈哈哈,这个结果时间也太久了,内存也太大了...

解法一思路优化

优化思路

在解法一中,我在判断每个格子能到达的格子处的时候,用的是for循环遍历能到达的,其实不必,只要是那个格子的数字,基本后面的那些数值都可以直接覆盖。

于是我想着进行优化,降低时间复杂度。

我们可以不用一个数组来存储可达的数据,而是用一个变量数值来表示,因为可达的都是前面所有的都能到达的。因此我们只需要一个int类型的arrive来记录,多少以前的格子是可以到达的即可。

解决

class Solution {
    public boolean canJump(int[] nums) {
        int length = nums.length;
        //首先定义一个元素来记录可达情况,默认0位置是可达
        int arrive = 0;
        //开始遍历数组
        for(int i=0;i<length;i++){
            if(nums[i]==0){
                //首先判断当前位置nums是不是0,要是0,直接跳过当前位置
                continue;
            }else if(i>arrive){
                //判断当前位置是否可以到达,不可以到达直接跳出循环
                break;
            }else{
                //站在轮到的位置,开始增加arrive,要是添加的位置大于arrive,就更新最大可达位置
                arrive = Math.max(arrive,i+nums[i]);
                //要是跟新后的arrive大于原数组的长度,证明可达,直接返回即可
                if(arrive>=length) return true;
            }
        }
        if(arrive>=length-1) return true;
        //要是遍历完还没有,就自动return false即可
        return false;
    }
}

结果

> 2023/07/16 15:42:36    
解答成功:
    执行耗时:2 ms,击败了91.57% 的Java用户
    内存消耗:42.9 MB,击败了19.94% 的Java用户

1

评论 (0)

取消
友情链接 文章阅读: 网站地图