数组跳跃游戏 Jump Game

来源:互联网 发布:淘宝一妹子买了古着店 编辑:程序博客网 时间:2024/05/20 06:40

题目源自于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.

思路一:依靠题目的规则循规蹈矩。

    解题的一个重要思想是想到各种极端情况,考虑周全。

    数组中的数都是非负整数,所以如果数组内没有0的话,一定是从开始能跳到最后的。如果有0的话,必须有办法跳到0的右边去。

极端的一个情况是这样的,543210...那么怎么也跳不到0右面。所以至少需要0的左边有个数的大于它到0的距离。

刚才只考虑了单独1个0,对于连续的多个0,就需要其左边的某个数大于到最右的0的距离。

另外,不管最后一个数是什么,只要到达它即可,所以我的首个研究对象应该是倒数第二个数。

    

解决步骤:根据这个思路,我对数组从右向左遍历。当遇到0或0s时,就开始判断其左边是否存在值大于到最右0的距离的数。当再次遇到0或0s时,若没有找到这样的数,则宣布失败(无法完成跳跃);若有这样的数,重新开始下一轮判断。该方法时间复杂度为O(N)。

注意每个while遍历的都应该做超出边界值的检查。

class Solution {public:    bool canJump(int A[], int n) {if(A == NULL || n <= 0)return false;  int i = n-2;int idx_0;int flag;  while(i >= 0){if(A[i] == 0){flag = 0;idx_0 = i;i--;while(i >=0 && A[i] == 0)i--;while(i >=0 && A[i] != 0){if(A[i] > idx_0 - i)flag = 1;i--;}if(flag == 0)return false;elsecontinue;}i--;}return true;    }};

思路二:贪心法。记录一个变量保持最远可达的位置。从左到右遍历时,不断刷新这个最远距离。

class Solution {public:    bool canJump(int A[], int n) {        int reach = 1;        for(int i=0;i<reach && reach < n;i++)            reach = max(reach, i + 1 + A[i]);        return reach >= n;    }};
思路三:动态规划法。不过在此就没必要了,空间复杂度太高。
class Solution {public:    bool canJump(int A[], int n) {        vector<int> v(n, 0);        for(int i=1;i<n;i++)        {            v[i] = max(v[i-1], A[i-1]) - 1; //状态递推            if(v[i] < 0)                 return false;        }        return v[n-1] >= 0;    }};

原创粉丝点击