45. Jump Game II
2015-07-24 15:25
351 查看
此题我一开始用的是DP,时间复杂度为O(N^2),虽然经过了一些优化,不过依然超时。最后参考了网上的答案,发现在这里用一种巧妙并且不太容易理解的贪心算法可以达到O(N)的时间复杂度,只不过在算法中要记录当前一跳所能到达的最远距离、上一跳所能到达的最远距离,和当前所使用跳数就可以了。另外需要注意的一点是:题意要求不一定非得跳到last index,越过去也算,这点需要特别强调。代码如下:
上述代码的例子如下:
初始状态: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。
注意,此题解法并不容易想得十分明白,要多琢磨和思考。
/* * 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。
注意,此题解法并不容易想得十分明白,要多琢磨和思考。
相关文章推荐
- 编译OpenVolumeMesh
- Java基础--常用正则匹配符号(必背,必须背,死都要背)
- 九度oj 1101
- Mongodb操作
- 精选30道Java笔试题解答
- 从付费产品说起
- Json格式对象转换为XML
- linux qt5.5发布 依赖库
- SQL常用语句总结
- Unity中使用C#脚本调用JS脚本的使用方法
- 读书笔记--如何阅读一本书
- IDE: 将程序加入右键菜单:
- NYOJ 638 小媛在努力(水)
- hdu5303(2015多校2)--Delicious Apples(贪心+枚举)
- iWatch报错: Authorizationsession time out
- 百度云推送的ios证书配置
- GitHub和SourceTree入门教程
- Linxu 压缩与解压缩
- XML vs JSON 谁是数据交换格式之王?
- 胶水语言