您的位置:首页 > 其它

45. Jump Game II

2015-07-24 15:25 351 查看
此题我一开始用的是DP,时间复杂度为O(N^2),虽然经过了一些优化,不过依然超时。最后参考了网上的答案,发现在这里用一种巧妙并且不太容易理解的贪心算法可以达到O(N)的时间复杂度,只不过在算法中要记录当前一跳所能到达的最远距离、上一跳所能到达的最远距离,和当前所使用跳数就可以了。另外需要注意的一点是:题意要求不一定非得跳到last index,越过去也算,这点需要特别强调。代码如下:

/*
* We use "last" to keep track of the maximum distance that has been reached
* by using the minimum steps "ret", whereas "curr" is the maximum distance
* that can be reached by using "ret+1" steps. Thus,
* curr = max(i+A[i]) where 0 <= i <= last.
*/
class Solution {
public:
int jump(int A[], int n) {
int ret = 0;//当前跳数
int last = 0;//上一跳可达最远距离
int cur = 0;//当前一跳可达最远距
for (int i = 0; i < n; ++i) {
//无法向前继跳直接返回
if(i>cur){  //有可能无论怎么跳,都不能到达终点或者越过终点,比如[3,2,1,0,4]。
return -1;
}
//需要进行下次跳跃,则更新last和当执行的跳数ret
if (i > last) {
last = cur;
++ret;
}
//记录当前可达的最远点
cur = max(cur, i+A[i]);
}

return ret;
}
};


上述代码的例子如下:

初始状态:cur表示最远能覆盖到的地方,用红色表示。last表示已经覆盖的地方,用箭头表示。起始时,它们都指向第一个元素。



接下来,第一元素告诉cur,可以向前走2步。于是:



下一循环中,i指向index 1(图中的元素3),发现i大于last能到的范围,于是进行跳跃。步数ret加1.同时要更新cur。因为发现了新的最远距离。



接下来,i继续前进,发现i=last,无需更新last和步数ret。更新cur。



i继续前进,发现i>last,更新last和步数。cur已经最大了。



最后,i到最后一个元素。遍历完成,返回ret。



注意,此题解法并不容易想得十分明白,要多琢磨和思考。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: