天天看点

算法设计与应用基础:第九周(1)

55. Jump Game

Add to List Description Hints Submissions Solutions

  • Total Accepted: 116148
  • Total Submissions: 396095
  • Difficulty: Medium
  • Contributor: LeetCode

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. 

Determine if you are able to reach the last index.

For example:

A = 

[2,3,1,1,4]

, return 

true

.

A = 

[3,2,1,0,4]

, return 

false

.

解题思路:看到这道题最容易想到的思路就是暴力求解:遍历数组内所有点,若它之前被标记过(到达过),就标记它可达范围内的所有点,最后检查最后一个点是否被标记。

直接的想法,但是不幸的是它的复杂度会达到n^2,在大数据面前就不可行了,所以需要采取更高效的方法进行“遍历”(这次要去掉一些没必要的步骤,也就是优化),这和最一开始讲的贪婪算法的基础内题很像,所以采取这个思路,每次记录在该点能到达的最大点(假装直接跳到这个点,这就是贪婪的关键,后面会证明这个算法的准确性),然后遍历在这个最大点和当前点之间的所有点,检查它们的nums[i]+i和最大点的关系,大于就修改。当遍历到i>furthest 的时候就结束(表明这时的furthest是能达到的最远点了)。

算法的正确性:每走一步都是走到的最远点(局部最优可以退出全局最优,因为是一步一步来的),这样就利用贪婪的算法过滤了没必要的遍历,大大减少了时间复杂度到n。

class Solution {
public:
    bool canJump(vector<int>& nums) {
        int size=nums.size();
        int furthest=0;//the furthest you can jump to till now;
        for(int i=0;i<size;i++)
        {
            if(i>furthest)
                break;
            else
                furthest=max(nums[i]+i,furthest);
        }
        return furthest>=size-1;
        
    }
};
           

 后记:greed algorithm的关键是证明局部最优是全局最优(因为往往局部最优容易去到);或者利用局部最优来接近全局最优。

继续阅读