dp 思路:规定dp[i]为到达第i个位置的最小步数,dp[i]一定是原来能到达这个位置的最小步数和其他位置能到达这个位置的最小步数加一的最小值(dp[i]=min(dp[i],dp[j]+1)).
java写代码的时候要注意初始值为0,所以排除数组长度为1的情况后要判断每一个点的dp值是否为0,如果为0,则设置为dp[i]+1。
java代码:
代码块
class Solution {
public int jump(int[] nums) {
int length = nums.length;
int dp[] = new int[length];
dp[0] = 0;
if(length==1)return 0;//排除为1的状况,否则后面动态规划时会让第一个点的步数变为1,从而答案错
int maxn =0; //当前能到达的最大下标
for(int i=0;i<=maxn;i++) {
maxn = Math.max(maxn, i+nums[i]);//更新最大下标
if(maxn>=length-1) {
dp[length-1]=dp[length-1]==0?dp[i]+1:Math.min(dp[length-1], dp[i]+1);
return dp[length-1];
}//当某一时刻能够达到最大下标时,直接进入最大下标,避免不必要的循环
for(int j=i+1;j<=i+nums[i]&&j<length;j++) {
dp[j]=dp[j]==0?dp[i]+1:Math.min(dp[j], dp[i]+1);
}//每次从当前结点出发,遍历每一个能达到的结点,并更新他们的dp值
}
return dp[nums.length-1];
}
}
c++代码
代码块
class Solution {
public:
int jump(vector<int>& nums) {
int length = nums.size();
vector<int> dp(length,0);
dp[0] = 0;
if(length==1)return 0;//排除为1的状况,否则后面动态规划时会让第一个点的步数变为1,从而答案错
int maxn =0; //当前能到达的最大下标
for(int i=0;i<=maxn;i++) {
maxn = max(maxn, i+nums[i]);//更新最大下标
if(maxn>=length-1) {
dp[length-1]=dp[length-1]==0?dp[i]+1:min(dp[length-1], dp[i]+1);
return dp[length-1];
}//当某一时刻能够达到最大下标时,直接进入最大下标,避免不必要的循环
for(int j=i+1;j<=i+nums[i]&&j<length;j++) {
dp[j]=dp[j]==0?dp[i]+1:min(dp[j], dp[i]+1);
}//每次从当前结点出发,遍历每一个能达到的结点,并更新他们的dp值
}
return dp[length-1];
}
};