Given an array of non-negative integers, you are initially positioned at the first index of the array.
Each element in the array represents your maximum jump length at that position.
Your goal is to reach the last index in the minimum number of jumps.
For example:
Given array A =[2,3,1,1,4]
The minimum number of jumps to reach the last index is2. (Jump1step from index 0 to 1, then3steps to the last index.)
方法1:分治法
//思路: 递归 + 缓存中间结果
int jump(int A[], int n)
{
if(A == NULL || n <= 1)return 0;
vector<int> vec(n, -1);//记录从i到n-1的最少次数
int start = 0;
int end = n -1;
return jumpCore(A, start, end, vec);
}
int jumpCore(int A[], int start, int end, vector<int> vec)
{
if(start >= end)
{
vec[start] = 0;
return 0;
}
if(vec[start] != -1) return vec[start]; //说明以前计算过直接返回
if(vec[start] == 0)
{
// 为0,则不能到达最后一个索引
vec[start] = 0x7FFFFFFF;
return vec[start];
}
int Min = 0x7FFFFFFF;
for(int i = 0; i <= start; ++i)
{
int step= jumpCore(A, start+i, end, vec);
if(step!= 0x7FFFFFFF) Min = min(Min, step+1);
}
vec[start] = Min;
return Min;
}
方法2:动态规划
//思路:设f(i)是到i位置最少的次数,因为i可以跳跃的步数<=A[i];
设i位置覆盖的范围是【start, end】,即从i位置可以跳跃的范围;
则 i < j < end, f(j) = min(f(i)+1, f(j)), f(i)+1表示从i位置只需跳跃1步就到位置j。。。
class Solution {
public:
int jump(int A[], int n) {
vector<int> dp; // dp存放都到各点的最小步数
for(int i = 0; i < n; i++)
{
int maxp = min(i+A[i],n-1); // 从i 出发能走到的最远距离
for (int j = i + 1; j <= maxp; j ++) {
if(dp[j] == 0 || dp[j] > dp[i]+1)
dp[j] = dp[i] + 1;
// 如果位置没被走过,或者可以用更少步数到达,则到达j点的步数为dp[i]+1
}
}
return dp[n-1];
}
};
方法3:贪心算法,每一步都往最远的跳,然后修正跳跃范围内的每一层,使得每一层也往最远的跳,最终的step就是最少的。比如i可跳跃的范围是【start, end】,接着对该范围在进行修正,既不断变化【start,end】,使得end >= n-1
int jump(int A[], int n)
{
if(A==NULL || n <= 1) return 0;
int step = 0;
int start = 0;
int end = 0;
while(start <= end)
{
++step;
int last = end;
for(int i = start; i < last; ++i)
{
int newend = A[i] + i;
if(newend >= n - 1) return step;
if(newend > end) end = newend;
}
start = last + 1;
}
return 0; //不能到达返回0
}
。。。。学习算法开始的小水逼。。。。