Leetcode-跳跃游戏I和II(动态规划)
Posted Booksort
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode-跳跃游戏I和II(动态规划)相关的知识,希望对你有一定的参考价值。
目录
这题可以用贪心来写,但是还是为了学习动态规划,从动态规划的角度去写。
存在型动态规划
判断是否存在结果
第一步:确定状态
从最后一步分析子问题,以确定状态
最后一步
当可以跳跃到最后一个位置n-1时,考虑是从位置i跳跃到n-1的位置。
i<n-1,且i+nums[i]>=n-1
从最后一步分析,要存在跳跃到最后一个位置的情况,满足两个条件
- 可以存在跳跃到位置i
- 最后一步不超过跳跃的最大距离i+nums[i]
子问题
从最后一步推出的子问题:能不能跳跃到位置i
结合最后一步与子问题确定状态的定义
状态:f(i)-能不能跳跃到位置i
确定状态转移方程
f(i)=OR< 0<=j<i >(f(j)&&j+nums[j]>=i)
要将位置i之前的所有位置都要判断一遍,只要存在一个满足条件,那么就能到达位置i
第二步:确定初始条件和边界条件
刚开始是从位置0开始跳跃,且,位置0跳跃到位置0的情况是可行的,所以f(0)=1
最后一个位置就是f(n-1),也就是问题的返回结果
第三步:确定计算顺序
由于要计算f(i),需要将i之前的所有下遍都进行计算,所有不仅仅要从0遍历到n01,还需要再来一个内循环遍历,从0到i-1去遍历,这样才能找出满足条件的情况,由于在leetcode中内循环从0向后遍历会超时,所有变成从后向前遍历,可以通过。
时间复杂度O(N^2),空间复杂度O(N)
代码实现
class Solution
public:
bool canJump(vector<int>& nums)
int len=nums.size();
int* arr=new int[len];
arr[0]=1;
for(int i=0;i<len;i++)
if(i==0)
continue;
arr[i]=0;
for(int j=i-1;j>=0;j--)
if(arr[j]&&nums[j]+j>=i)
arr[i]=1;
break;
return arr[len-1];
;
最大/小型动态规划
本题同样用贪心实现的话,更为简单,快捷。
从动态规划的角度去解题
本体要求解从0位置跳跃到n-1位置的最少跳跃次数,符合最大最小问题
第一步:确定状态
从最后一步分析,以得到一个递归的关系
最后一步
从位置i跳跃到位置n-1,那么就是最少的跳跃次数到位置i+1就可以得到跳跃到n-1的位置。
如果假设位置i是最少跳跃次数到位置n-1的情况的前一步,那么下一步该分析的是跳跃到i位置的最少次数是多少。
子问题
跳跃到i位置的最少次数
确定状态
f(i):跳跃到位置i的最少跳跃次数
确定状态转移方程
f(i)=min< 0<=j<i >( f(j)+1 )
位置i之前的位置都需要去寻找判断,还需要满足条件j+nums(j)>=i
第二步:确定初始条件和边界
最开始肯定是从位置0开始向后跳跃。且,位置0肯定是可以到达的,设置最少跳跃次数为0,不需要跳跃
第三步:计算顺序
由于要计算f(i),需要将i之前的所有下遍都进行计算,所有不仅仅要从0遍历到n01,还需要再来一个内循环遍历,从0到i-1去遍历,这样才能找出满足条件的情况,由于在leetcode中内循环从0向后遍历会超时,所有变成从后向前遍历,可以通过。
由于判断最少次数,可以初始设值为INT_MAX,然后去内循环中依次比骄傲最小值,比较前要判断是否符合到达i位置的条件
时间复杂度O(N^2),空间复杂度O(N)
代码实现
class Solution
public:
int jump(vector<int>& nums)
int len = nums.size();
int* arr=new int[len];
arr[0]=0;
for(int i=1;i<len;i++)
int minnum=INT_MAX;
for(int j=i-1;j>=0;j--)
if(j+nums[j]>=i)
minnum=min(minnum,arr[j]+1);
arr[i]=minnum;
return arr[len-1];
;
以上是关于Leetcode-跳跃游戏I和II(动态规划)的主要内容,如果未能解决你的问题,请参考以下文章