Given an array of non-negative integers, you are initially positioned at the first index of the array.html
Each element in the array represents your maximum jump length at that position. 数组
Determine if you are able to reach the last index.post
For example:
A = [2,3,1,1,4]
, return true
.url
A = [3,2,1,0,4]
, return false
.spa
这是Jump Game系列的第一题,判断根据给出的数组能不能到达最后一个index。若是能够的话,则返回True。code
使用DP的话,设f(i)表示为可否到达index为i的位置。分解子问题则 f(i) = OR(f(j) and j + A[j] > i)即若是小于i的index j上若是跳一步能够到达i, 则i能够到达。根据这个给出DP的代码以下:htm
class Solution(object): def canJump(self, nums): """ :type nums: List[int] :rtype: bool """ if not nums: return true n = len(nums) res = [False]*n res[0] = True for i in xrange(1,n): for j in xrange(i,-1,-1): #倒序,能够减小遍历的次数 if res[j] == True and nums[j]+j>=i: #剪枝,防止超时。 res[i] = True break return res[-1]
注意由于有多种可能的路径,因此一旦找到使OR为真的j,就须要进行剪枝。不然DP的复杂度就是O(n^2),在Leetcode上会超时。blog
这一题最优的解法为贪心,O(n)。作法是维护一个在index i时可到达的最远距离reach,这个reach不必定是在index i处跳nums[i]到达的,能够是在i以前的index上到达的,是一个历史最优。element
1.能继续循环,处理到i的条件为i<=reach。即i处在历史可到达的最远距离范围中。get
2.reach的更新是 reach = max(reach,i+nums[i]).
3.判断能够达到终点的条件是reach>= len(nums)-1.
由于每一步维护的是一个局部最优解,因此是贪心的解法,代码以下:
class Solution(object): def canJump(self, nums): """ :type nums: List[int] :rtype: bool """ if not nums: return True reach, i = 0, 0 while i <= reach and reach < len(nums): reach = max(reach,nums[i]+i) i = i+1 return reach >= len(nums)-1
空间复杂度也为O(n)。
上述这种解法也能够认为是DP,和Maximum Subarray很是相似,能够认为咱们维护了一个local最优,即当前位置能够跳到的最远距离:nums[i]+i,全局最优:历史位置上能够到达的最远距离:即reach.每次更新局部最优时,同步更新全局最优。