您的位置:首页 > 其它

LeetCode 55. Jump Game

2016-01-26 23:48 295 查看
题目描述

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.

解题思路

第一思路是宽度优先搜索,依次步进,直到找到走到终点输出true或者所有路径都走完仍然没有到达终点,则输出false。第二种思路是类似于动态规划。仍然是首先给出超时的解法,然后是正确的解法。

解法一(超时):宽度优先搜索

用一个栈保存数组中可以到达的点,对于每个数,该值为sums[i],则将i后面的sums[i]个值放入数组中,直到把最后一个元素放入栈,则返回true;如果栈为空并且最后一个元素仍然未入栈,则返回false。

为了防止同一个元素重复入栈,设置一个bool数组,标记元素是否曾入栈。

时间复杂度为O(n^2)。

class Solution {
public:
bool canJump(vector<int>& nums) {
int n=nums.size();
stack<int> s;
vector<bool> b(n+1,false);
s.push(0);
b[0]=true;
while(!s.empty())
{
int i=s.top();
s.pop();
if(i>=n-1)return true;
for(int j=1;j<=nums[i];j++)
if(!b[i+j])
{
s.push(i+j);
b[i+j]=true;
}
}
return false;
}
};


解法二(Accept)

枚举每一位数时都在判断是否能够到达该点且能否继续往前走,假设在某一瞬间,index=m 的位置已经到达,那么 index=n (n<=m) 的位置肯定可达,维护一个最右边的可达点,如果当前枚举点在该点的左侧,那么当前点已经到达,否则即可停止遍历(因为右边的点再也不可能到达)。时间复杂度为O(n)。

class Solution {
public:
bool canJump(vector<int>& nums) {
int n=nums.size();
int right=0;
for(int i=0;i<n;i++)
{
if(i>right)break;
right=max(right,i+nums[i]);
}
return right>=n-1;
}
};


参考文献:Jump Game 的三种思路 - leetcode 55. Jump Game
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode