我正在调试以下问题并发布代码。想知道代码是否正确。我目前的疑问是,i
是否应该总是增加(在这一行 - for (;i <= end; i++)
)?
给定一个非负整数数组,您最初位于数组的第一个索引处。
数组中的每个元素代表该位置的最大跳跃长度。
您的目标是以最小跳数达到最后一个索引。
例如:
给定数组A = [2,3,1,1,4]
,
到达最后一个索引的最小跳转次数是2。
(从索引0到1跳1步,然后从最后一个索引跳3步。)
class Solution {
public:
int jump(vector<int>& nums) {
int i = 0, n = nums.size(), step = 0, end = 0, maxend = 0;
while (end < n - 1) {
step++;
for (;i <= end; i++) {
maxend = max(maxend, i + nums[i]);
if (maxend >= n - 1) return step;
}
if(end == maxend) break;
end = maxend;
}
return n == 1 ? 0 : -1;
}
};
答案 0 :(得分:3)
假设给定的数组是<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
。从第i个位置开始,你可以跳A[1..n]
。您已经计算了所有j&gt; = i&amp;&amp;的结果J&LT; = N。所以现在
1 or 2 or 3...A[i]
通过这种方式,您可以计算所有内容。
O(n ^ 2)时间复杂度。
您也可以在ans[i]=min(ans[i+j],ans[i]) where i+j<=n && j=1,2,...A[i]
中进行计算。从一个位置开始,您将始终移动到具有最高O(n)
值的位置。
我的意思是假设你处于i+A[i]
位置。接下来,您将移至j
位置,以使j
最大。
如果其中一个元素是最后一个元素,则跳转到最后一个元素。否则,跳转到具有最大j+A[j]
的元素。
O(n)解决方案......
j+A[j]
Jump 2 3 1 1 4
position 1 2 3 4 5
j+A[j] 3 5 4 5 9
^ . . . .
. ^ . . .
. . . . ^ ---> so 2 jumps.. :)
答案 1 :(得分:2)
我在这里看到两种解决方法。
您只需要从索引0开始,并且对于每个索引i
尝试提前跳转到1到a[i]
索引,同时保持最后一个索引的最佳结果。它具有很高的算法复杂度,因此只有在效率真的无关紧要或n
非常小时才应该选择。
算法将如下所示:
int best = 2147483647;
vector<int> A;
void Jump(int index, int step)
{
if (step > best)
{
// for positive values, if step > best we won't improve our result
// avoid worthless calculations
return;
}
if (index == A.size() - 1)
{
if (step < best) best = step;
return;
}
int maxJumps = A[index];
for (int i = index; i <= min(index + maxJumps, A.size() - 1); i++)
{
Jump(i, step + 1);
}
}
int main()
{
// read input
Jump(0, 0);
}
对于您的情况,递归将采用这种方式:
Start from A[0] (equal to 2) step = 0
> A[0+1] with step+1 (equal to 3) step = 1
>> A[1+1] with step+1 (equal to 1) step = 2
>>> A[2+1] with step+1 (equal to 1) step = 3
>>>> A[3+1] with step+1 (equal to 4) step = 4
>>>>> End of array. Compare step(4), best (MAXINT) best = 4
>> A[1+2] with step+1 (equal to 1) step = 2
>>>> A[3+1] with step+1 (equal to 4) step = 3
>>>>> End of array. Compare step (3), best (4) best = 3
>> A[1+3] with step+1 (equal to 4) step = 2
>>>>> End of array. Compare step(2), best (3) best = 2
> A[0+2] with step+1 (equal to 1) step = 2
>>> A[2+1] with step+1 (equal to 1) step = 3
>>>> A[3+1] with step+1 (equal to 4) step = 4
>>>>> End of array. Compare step(4), best(2) best = 2
<强>动态。智能和高效
此方法使用Dynamic programming。让我们得到一个与数组A长度相同的数组B
。让B[i]
表示&#34; 最小需要多少步才能跳转到A [i ]&#34 ;.如果我们知道B[i]
,那么我们可以说我们可以跳转到i + 1
的所有可能索引(从i + A[i]
到B[i] + 1
)。因此,您只需要从0到N-1遍历数组并向前看,改进每个i
到i + a[i]
的结果。
这样的事情:
vector<int> A, B;
int n;
int main()
{
// read n; read A of size n
B.reserve(n); // B should be the same size and initialized with zeroes (by default)
B[0] = 0; // not obligatory, 0 by default, just for clearness
for (int i = 0; i < n - 1; i++)
{
for (int j = i + 1; j <= min(i + A[i], n - 1); j++)
{
// improve result if we weren't there yet or if we can come to A[j]
// faster if we go from A[i]
if (B[j] == 0 || B[i] + 1 < B[j])
B[j] = B[i] + 1;
}
}
}
算法将以这种方式工作:
A = 2 3 1 1 4
B = 0 0 0 0 0
i = 0, improve 0+1, 0+2
B = 0 1 1 0 0
i = 1, improve 1+1, 1+2, 1+3
B = 0 1 2 2 2
i = 2, no improvements
i = 3, no improvements
答案存储在B[n - 1]
我已经实施了working IDEOne demo。
答案 2 :(得分:1)
我正在分享算法。现在, BFS 描述如下:
int A[N]; // It contains the initial values
int result[N]; // Initialise all with positive infinty or INT_MAX in C
bool visited[N]; // Initially, all initialise with '0' means none of the index is visited
queue Q; // create a queue
index = 1
cost = 0
push index in rear of Q.
result[index] = cost
visited[index] = true
while(Q is not empty) {
index = pop the value from the front of the Q.
cost = cost + 1
for(i in 1 to A[index]) {
temp_index = index + i;
if(temp_index <= N AND visited[temp_index] == false) {
push temp_index in rear of Q.
result[temp_index] = cost
visited[temp_index] = true
}
}
}
// Finally print the value of result[N]
print result[N]
注意:还存在 DP 方法,其时间复杂度 O(n 2 的)强>