Problem
Notes
求index从0到n-1的最小跳数,cases保证有解。
一开始想到dp,用dp[i]记录从0跳到i下标的最小跳数。状态转移方程为dp[i+j]=dp[i+j]<dp[i]+1?dp[i+j]:dp[i]+1。该解法超时。
查题解的时候发现此题也能有贪心解法,时间复杂度o(n)。
贪心法,维护一个常量far记录当前能到的最远下标,若far已经大于等于n-1,则结束。否则,从i到far遍历,看i+nums[i]是否大于far,用这个区间里算出的i+nums[i]的最大值去更新far,这样更新一次,步数+1。最后返回步数即可。
发现做这题的过程和55题时是一样的,还是没把这题顺利解出来,好菜啊呜呜呜
Codes
dp做法,超时
class Solution {
public:
int jump(vector<int>& nums) {
int n=nums.size();
if(n==1) return 0;
int inf=INT_MAX;
int dp[n];
for(int i=0;i<n;++i) dp[i]=inf;
dp[0]=0;
for(int i=0;i<n;++i)
{
for(int j=1;j<=nums[i];++j)
{
if(i+j>=n-1) return dp[n-1]<dp[i]+1?dp[n-1]:dp[i]+1;
dp[i+j]=dp[i+j]<dp[i]+1?dp[i+j]:dp[i]+1;
// dp[i+j]=min(dp[i+j],dp[i]+1);
}
}
return dp[n-1];
}
};
贪心思路
class Solution {
public:
int jump(vector<int>& nums) {
int n=nums.size();
if(n==1) return 0;
int cnt=0;
int far=0;
int i=0;
while(i<n)
{
int temp=-1;
while(i<=far)
{
temp=temp>(i+nums[i])?temp:(i+nums[i]);
++i;
}
far=temp;
cnt++;
if(far>=n-1) return cnt;
}
return cnt;
}
};