欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > [LeetCode 45] 跳跃游戏2 (Ⅱ)

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

2025/4/19 9:00:31 来源:https://blog.csdn.net/qq_45371462/article/details/147216756  浏览:    关键词:[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 & rightsize_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;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词