力扣日记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 <= numsi <= 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)

思路总结

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

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

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

相关推荐
郝学胜-神的一滴17 分钟前
游戏设计:原型与开发 11:用概率与电子表格搞定骰子系统
程序人生·游戏·游戏策划·1024程序员节·游戏设计
hold?fish:palm1 小时前
40 二叉树的直径
c++·leetcode
treesforest2 小时前
游戏账号安全风险分层方案:IP信号分层与人机复核实践
tcp/ip·安全·游戏·1024程序员节
guo_wen_qiang2 小时前
二叉树的层序遍历-使用双端队列Deque
算法·leetcode·1024程序员节
爱读书的小胖3 小时前
LeetCode 55 跳跃游戏 C 语言解题分析
c语言·数据结构·算法·leetcode·1024程序员节
Navigator_Z4 小时前
LeetCode //C - 1300. Sum of Mutated Array Closest to Target
c语言·算法·leetcode
Raspberry_Pi_官方账号4 小时前
隆重推出《Raspberry Pi 复古游戏指南》
游戏·树莓派·diy·raspberry pi
凯瑟琳.奥古斯特5 小时前
力扣1016高效解法:剪枝优化技巧
开发语言·c++·算法·leetcode·职场和发展
Oiiouui5 小时前
针对Godot-GridGame(网格游戏)的DI注入+RefCounted数据驱动信号流架构设计的研究(全程开源)
游戏·游戏引擎·godot·1024程序员节
qz_Serene6 小时前
练习算法题:双指针 -cpp
c++·算法·leetcode·1024程序员节