45. Jump Game II

此题我一开始用的是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。



 注意,此题解法并不容易想得十分明白,要多琢磨和思考。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值