栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

leetcode 55 跳跃游戏

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

leetcode 55 跳跃游戏

前言

题目:55. 跳跃游戏

参考题解:跳跃游戏-代码随想录


提交代码 方法一:回溯

每一步可以选择不同的长度。在跨出一步后,后面在此基础上,继续前进。很明显的回溯思路。

我按照回溯思路,码出代码,通过75/166之后,代码超时。我看了下超时的测试用例:[9997,9996,9995,……3,2,1,0,0],需要计算 9997 ∗ 9996 ∗ … … ∗ 3 ∗ 2 ∗ 1 9997*9996*……*3*2*1 9997∗9996∗……∗3∗2∗1次。这是回溯中,最坏的一种情况。

class Solution {
public:
    bool backTracking(vector& nums, int start, int& pass){
        if(pass >= nums.size()-1)
            return true;
        
        for(int step=nums[start]; step>0; step--){
            pass += step; // 尝试向前走step
            if(backTracking(nums,start+step,pass)) return true; // 成功则层层true退出
            pass -= step; // 退回step
        }
        return false; // 当前位置,所有step尝试均为到达,返回false,进行回退
    }

    bool canJump(vector& nums) {
        int start = 0;
        int pass = 0;
        return backTracking(nums,start,pass);
    }
};
方法二:避免陷入0

为了避免陷入方法一的问题,我们遇到0的时候,进行判断。

  • 序列只有一个元素,且该元素为0,不用前进,坐享其成。
  • 序列均为非负整数,只要不是0,均会前进,所以只有0需要判断。判断是否这个0是否无法绕过。

根据这个指导思想,我码出了方法二代码。但是这种方法存在一个问题,需要考虑的面面俱到。很有可能漏掉考虑某些情况。下面的代码通过141/166。

#include 
#include 

using namespace std;

class Solution {
public:
    bool canJump(vector& nums) {
        if(nums.size()==1 && nums[0]==0) // 只有一个元素,且该元素为0,不用前进,坐享其成
            return true;

        for(int i=0; i=0){ // 遇到0,只要前面的数字不都掉入这个位置,也没关系
                if(nums[j] != val)
                    break;
                j--;
                val++;
            }
            if(j>=0 && nums[j]!=0 ) // 当前0,必须在遇见之前0之前,做出决断
                continue; // 0位置可以避过,继续前进
            else
                return false; // 0位置无法避过,必然入坑之后,无法动弹,返回false
        }
        return true;
    }
};

int main(void){
    vector nums = {2,0,0};
    Solution s;
    cout< 
方法三:跨域区间 

不断向前移动,记录可以跨越到达最远的位置。当最远位置大于目标位置,成功。

这个思路比较简单,有效。成功通过所有测试用例。

#include 
#include 
#include 

using namespace std;

class Solution {
public:
    bool canJump(vector& nums) {
        int start = 0;
        int pass = start + nums[start];
        int max_pass = pass;

        if(max_pass>=nums.size()-1)
            return true;
        
        for(int i=start+1; i<=max_pass; i++){ 
            pass = i + nums[i];
            max_pass = max(max_pass,pass); // 不断前进,更新最远可到达位置
            if(max_pass >= nums.size()-1)
                return true;
        }

        return false;
    }
};

int main(void){
    vector nums = {3,2,1,0,4};
    Solution s;
    cout<
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/302510.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号