当前位置: 首页 > news >正文

[LeetCode 45] 跳跃游戏2 (Ⅱ)

题面:

LeetCode 45 跳跃游戏2
在这里插入图片描述

数据范围:

1 ≤ n u m s . l e n g t h ≤ 1 0 4 1 \le nums.length \le 10^4 1nums.length104
0 ≤ n u m s [ i ] ≤ 1000 0 \le nums[i] \le 1000 0nums[i]1000
题目保证可以到达 n u m s [ n − 1 ] nums[n-1] nums[n1]

思路 & code:

1. dp暴力思路

往前找,如果前面某个点能到当前点 i n d e x index index,及存在 k < i k<i k<i 使得 k + n u m s [ k ] ≥ i k+nums[k] \ge i k+nums[k]i,则更新 dp(dp[i]存储到当前 i i i 点所需最小步长), d p [ i ] = m i n ( d p [ i ] , d p [ k ] + 1 ) dp[i] = min(dp[i], dp[k]+1) dp[i]=min(dp[i],dp[k]+1)

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

size_t n = nums.size();
vector<int> dp(n, 0x3f3f3f3f);
dp[0] = 0;
for(int i = 1; i < n; ++i)
    for(int k = 0; k <= i; ++k)
       if(k + nums[k] >= i)
         dp[i] = min(dp[i], dp[k] + 1);

2. dp + 贪心 + 双指针:即第一个跳到当前点 i i i 的点 j j j,必是步数最少的。

**证明:**假设有一个点 p > j p > j p>j, 其跳到点 i i i 的步数小于点 j j j 跳到点 i i i 的步数。则有 d p [ p ] + 1 < d p [ j ] + 1 dp[p] + 1 < dp[j] + 1 dp[p]+1<dp[j]+1, 即 d p [ p ] < d p [ j ] dp[p] < dp[j] dp[p]<dp[j]。由于 d p [ k ] dp[k] dp[k] 存储的是跳到 k k k 点的最短步长,又 j < p j < p j<p, 故能跳到 p p p 点的一定也能跳到 j j j 点,即 d p [ j ] ≤ d p [ p ] dp[j] \le dp[p] dp[j]dp[p] 的,故原式不成立。所以第一个跳到当前点i的点j必是步长最小的。

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

size_t n = nums.size(), j = 0;
vector<int> dp(n, 0);
for(size_t i = 1; i < n; ++i) {
    while(j + nums[j] < i) ++j;
    dp[i] = dp[j] + 1;
}
return dp[n-1];

3. 贪心+滑动窗口

维护一个当前能到达的最大边界(窗口),每次更新边界时,步数++。通俗理解就是因为当前的最大边界就是这一步能跳到的,如果想跳出更大的,则需要继续跳一步才行。

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

int jump(vector<int>& nums) {
    /* 维护两个端点,left & right
    size_t n = nums.size(), left = 0, right = 0;
    size_t maxPos = 0, step = 0;
    while(right < n - 1) {
        for(auto i = left; i <= right; ++i)
            maxPos = max(maxPos, i + nums[i]);
        left = right + 1;
        right = maxPos;
        ++ step;
    }
    return step;
    */
    /* 
    优化, left其实没有贡献, 一遍遍历只维护right即可
    */
    size_t n = nums.size(), step = 0;
    size_t right = 0, maxPos = 0;
    for(size_t i = 0; i < n - 1; ++i) {
        maxPos = max(maxPos, i + nums[i]);
        if(i == right) {
            right = maxPos;
            ++ step;
        }
    }
    return step;
}

相关文章:

  • Python高级爬虫之JS逆向+安卓逆向1.4节:数据运算
  • Solidity私有函数和私有变量区别,私有变量可以被访问吗
  • 在轨道交通控制系统中如何实现μs级任务同步
  • KiCad 9.0:如何在 PCB 上暴露铜皮(开窗)
  • go中new和make有什么异同?
  • [LeetCode 1306] 跳跃游戏3(Ⅲ)
  • AD利用转换工具快速生成异形焊盘
  • 从Ampere到Hopper:GPU架构演进对AI模型训练的颠覆性影响
  • TLA:用于接触-丰富操作的触觉-语言-动作模型
  • Profibus DP转ModbusTCP网关通讯案例解析
  • Arrays.asList() 隐藏的陷阱
  • 论文导读 | 基于GPU的子图匹配算法
  • #4 我们为什么使用物联网? 以及 物联网的整体结构
  • Python六大数据类型与可变类型
  • Thread类的基本用法
  • 用Webpack 基础配置快速搭建项目开发环境
  • 支持多项检测的多段环形光源 助力金属零件缺陷检测
  • Wincc7.5 对于此版本的wincc,许可证的存储介质必须插入usb接口
  • 项目风险的早期识别与应对清单
  • Swift观察机制新突破:如何用AsyncSequence实现原子化数据监听?
  • 明查|俄罗斯征兵部门突袭澡堂抓捕壮丁?
  • “30小时不够”,泽连斯基建议延长停火至30天
  • 天工机器人获首个人形机器人半马冠军
  • 梅德韦杰夫:如果欧盟和美国 “撒手不管”,俄罗斯会更快解决俄乌冲突
  • 报告:去年物业服务百强企业营业收入均值同比增长3.52%
  • 思南读书会500期了,这是上海最具温度的阅读文化样本