力扣日记3.19-【贪心算法篇】55. 跳跃游戏

力扣日记:【贪心算法篇】55. 跳跃游戏

日期:2024.3.19

参考:代码随想录、力扣

55. 跳跃游戏

题目描述

难度:中等

给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。

判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。

示例 1:

输入:nums = [2,3,1,1,4]

输出:true

解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。

示例 2:

输入:nums = [3,2,1,0,4]

输出:false

解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 , 所以永远不可能到达最后一个下标。

提示:

  • 1 <= nums.length <= 10^4
  • 0 <= nums[i] <= 10^5

题解

cpp 复制代码
class Solution {
public:
#define SOLUTION 2
#if SOLUTION == 1   /*回溯法,超出时间限制*/
    bool canJump(vector<int>& nums) {
        return backtracking(nums, 0);
    }
    bool backtracking(vector<int>& nums, int startindex) {
        // 终止条件:如果已经到达最后一个下标
        if (startindex >= nums.size() - 1) {
            return true;
        }
        // for 循环
        // 从大到小横向遍历这个元素值(选择可以跳跃的长度)
        for (int i = nums[startindex]; i > 0; i--) {
            startindex += i;    // 跳到下一个位置
            if (backtracking(nums, startindex)) return true;
            // 如果当前跳跃步数无法到最后一个坐标,则回溯
            startindex -= i;
        }
        return false;
    }
#elif SOLUTION == 2
    bool canJump(vector<int>& nums) {
        // 看最大覆盖范围!但每次只移动一个长度(关键!!!),并不断更新最大覆盖范围(最大可到达的下标)
        // 局部最优:获取每个位置当前可到达的最大下标
        // 全局最优:遍历可到达的全部元素,找到其中最大的可到达下标即为总的最大下标
        int curMaxIndex = 0;
        for (int i = 0; i <= curMaxIndex; i++) {    // 最大只能到curMaxIndex(不断更新)
            if (i + nums[i] > curMaxIndex) {    // 如果新的当前位置可到达的最大长度 比 curMaxIndex 大,则更新
                curMaxIndex = i + nums[i];
            }
            if (curMaxIndex >= nums.size() - 1) {   // 如果已能到达最后一个下标,则返回true
                return true;
            }
        }
        return false;
    }
#endif
};

复杂度

贪心算法:

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

思路总结

  • 一开始尝试用回溯算法,虽然思路是正确的,但回溯法相当于穷举,结果超出时间范围了
  • 参考代码随想录的思路:
    • 看最大覆盖范围!注意每次只移动一个长度(关键!!!),并不断更新最大覆盖范围(即最大可到达的下标)

      • 这样的话,就可以不管究竟在每个位置要跳几步,只要知道在覆盖范围内的每个位置能到达的最大下标即可(能覆盖到最大下标即成功)。
    • 局部最优:获取每个位置当前可到达的最大下标

    • 全局最优:遍历覆盖范围内可到达全部元素,找到其中最大的可到达下标即为总的最大下标

相关推荐
Kuo-Teng8 小时前
LeetCode 160: Intersection of Two Linked Lists
java·算法·leetcode·职场和发展
wanhengidc9 小时前
云手机通常使用什么架构
服务器·网络·安全·游戏·智能手机·云计算
橘颂TA11 小时前
【剑斩OFFER】算法的暴力美学——点名
数据结构·算法·leetcode·c/c++
愚润求学14 小时前
【动态规划】专题完结,题单汇总
算法·leetcode·动态规划
·白小白15 小时前
力扣(LeetCode) ——43.字符串相乘(C++)
c++·leetcode
愿没error的x16 小时前
动态规划、贪心算法与分治算法:深入解析与比较
算法·贪心算法·动态规划
一匹电信狗20 小时前
【C++11】Lambda表达式+新的类功能
服务器·c++·算法·leetcode·小程序·stl·visual studio
在等晚安么20 小时前
力扣面试150题打卡
算法·leetcode·面试
User_芊芊君子1 天前
【LeetCode经典题解】递归破解对称二叉树之谜
算法·leetcode·职场和发展
Rock_yzh1 天前
LeetCode算法刷题——49. 字母异位词分组
数据结构·c++·学习·算法·leetcode·职场和发展·哈希算法