给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个位置。
示例 1:
输入: [2,3,1,1,4] 输出: true 解释: 我们可以先跳 1 步,从位置 0 到达 位置 1, 然后再从位置 1 跳 3 步到达最后一个位置。
示例 2:
输入: [3,2,1,0,4] 输出: false 解释: 无论怎样,你总会到达索引为 3 的位置。但该位置的最大跳跃长度是 0 , 所以你永远不可能到达最后一个位置。
倒序递规超出时间限制
思路倒着搜索:[index…nums.size()-1]能否达到
class Solution(object):
def canJump(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
return self._canJump(nums,0)
def _canJump(self,nums,index):
if index==len(nums)-1:
return True
if nums[index]+index>=len(nums)-1:
return True
for i in range(nums[index]):
if self._canJump(nums,index+i+1):
return True
return False
用记忆划搜索对上述方法进行优化(时间超时)
class Solution(object):
def canJump(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
mem=[None]*len(nums)
return self._canJump(nums,0,mem)
def _canJump(self,nums,index,mem):
if mem[index]!=None:
return mem[index]
if index==len(nums)-1:
mem[index]==True
return True
if nums[index]+index>=len(nums)-1:
mem[index]==True
return True
for i in range(nums[index]):
if self._canJump(nums,index+i+1,mem):
mem[index]=True
return True
break
mem[index]==False
return False
后向动态规划(python 时间超限制,c++ 版本的随缘)
class Solution(object):
def canJump(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
mem=[None]*len(nums)
mem[-1]=True
for i in range(len(nums)-2,-1,-1):
if nums[i]+i>=len(nums)-1:
mem[i]=True
continue
elif nums[i]>0:
for j in range (nums[i]):
if mem[j+i+1]==True:
mem[i]= True
break
else:
mem[i]=False
return mem[0]
后向动态规划(通过是随机的看缘分)
class Solution {
public:
bool canJump(vector<int>& nums) {
vector<bool>mem(nums.size(),false);
mem[nums.size()-1]=true;
for(int index=nums.size()-2;index>=0;index--)
{
if (nums[index]+index>=nums.size()-1)
mem[index]=true;
else{
for(int i=nums[index]+index;i>index;i--)
{
if (mem[i]==true)
{
mem[index]=true;
break;
}
}
}
}
return mem[0];
}
};
贪心算法
class Solution {
public:
bool canJump(vector<int>& nums) {
int max_index=0;
for(int i=0;i<nums.size();i++){
if (i>max_index)
return false;
max_index=max(nums[i]+i,max_index);
}
return true;
}
};
class Solution {
public:
bool canJump(vector<int>& nums) {
// [index,,,nums.size()-1]
// last 表示能够到达nums末端的最左边位置
int last=nums.size()-1;
for(int index=nums.size()-2;index>=0;index--)
{ if(nums[index]+index>=last)
last=index;
}
return last==0;
}
};
自顶向下动态规划(超出时间)
class Solution:
def canJump(self, nums: List[int]) -> bool:
# [0...index]
mem=[False]*len(nums)
mem[0]=True
for index in range(1,len(nums)):
for i in range(index):
if mem[i]==True and nums[i]+i>=index:
mem[index]=True
break
return mem[len(nums)-1]
自顶向下递规(超出时间)
class Solution:
def canJump(self, nums: List[int]) -> bool:
# [0...index]
return self._canJump(nums,len(nums)-1)
def _canJump(self,nums,index):
if index ==0:
return True
for i in range(index-1,-1,-1):
if self._canJump(nums,i)==True and nums[i]+i>=index:
return True
return False
最后执行的输入:
[2,0,6,9,8,4,5,0,8,9,1,2,9,6,8,8,0,6,3,1,2,2,1,2,6,5,3,1,2,2,6,4,2,4,3,0,0,0,3,8,2,4,0,1,2,0,1,4,6,5,8,0,7,9,3,4,
自顶向下递规(记忆划搜索超出时间)
class Solution:
def canJump(self, nums: List[int]) -> bool:
# [0...index]
mem=[None]*len(nums)
mem[0]=True
return self._canJump(nums,len(nums)-1,mem)
def _canJump(self,nums,index,mem):
if mem[index]!=None :
return mem[index]
if index ==0:
mem[index]=True
return True
for i in range(index):
if self._canJump(nums,i,mem)==True and nums[i]+i>=index:
mem[index]=True
return True
mem[index]=False
return False
最后执行的输入:
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
自顶向下递规(记忆划搜索优化)
class Solution:
def canJump(self, nums: List[int]) -> bool:
# [0...index]
mem=[None]*len(nums)
mem[0]=True
return self._canJump(nums,len(nums)-1,mem)
def _canJump(self,nums,index,mem):
if mem[index]!=None :
return mem[index]
if index ==0:
mem[index]=True
return True
for i in range(index-1,-1,-1):
if self._canJump(nums,i,mem)==True and nums[i]+i>=index:
mem[index]=True
return True
mem[index]=False
return False
自顶向下动态规划(优化)
class Solution:
def canJump(self, nums: List[int]) -> bool:
# [0...index]
mem=[False]*len(nums)
mem[0]=True
for index in range(1,len(nums)):
for i in range(index-1,-1,-1):
if mem[i]==True and nums[i]+i>=index:
mem[index]=True
break
return mem[len(nums)-1]