問題描述
You are given an integer array
nums
. You are initially positioned at the array's first index, and each element in the array represents your maximum jump length at that position.Return
true
if you can reach the last index, orfalse
otherwise解釋:
給定一個數字nums,你被放在第一個位置上,nums中的每一個元素代表你處於該位置最多可以跳幾步。
如果能跳到最後一個位置,返回true;否則返回false
案例
Input: nums = [2,3,1,1,4] Output: true Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index.\ 解釋: 第一個位置跳1步道第二個位置,第二個位置跳3步到最後一個位置
基本思想-1
設nums的大小為size,構建長度為size的陣列dp。
- dp[i] 表示的是
nums[0~i-1]
有多少種方法可以跳至i位置,則dp[i] 的更新依賴於nums[0~i-1]
, 具體如下:- 假設
0<=j <=i-1
, 如果 nums[j] + j >= i,那麼說明由j位置可以跳到i,此時 dp[i] = dp[j] ,因為可能存在多個滿足上述條件的j,所以 公式修改為 dp[i] = dp[j] + dp[i]
- 假設
時間複雜度\(o(n^2)\)
程式碼實現如下
def canJump(self, nums: List[int]) -> bool:
size = len(nums)
if size <=1 : return True
dp = [0] * size
dp[0] = 1 # dp[i] 跳到第i個位置的方法數目
for i in range(1,size):
for j in range(0,i):
if (nums[j] > 0) and (dp[j] > 0) and ((nums[j] + j ) >= i):
dp[i] = dp[i] + dp[j]
return dp[size-1]>0
上述程式碼報錯,提示 Time Limit Exceeded
,測試用例明顯陣列太大了,時間複雜度太高了
最佳化
記錄0~i-1最多能跳到那個位置x,
對於位置i,只需要判斷i位置是否能到達 & i位置是否可以繼續跳。
當i<=x ,表示i位置可以跳到。知道進行到倒數第二個位置,此時 0~size-1的最大能跳躍位置是x,如果\(x >= size-1\), 則表示可以跳到最終位置,否則表示不能跳到
程式碼
C++
bool canJump(vector<int>& nums) {
int size = nums.size();
if (size<=1) return true;
if (nums[0]<=0) return false;
int maxLoc = nums[0];
int maxLocIndex = 0;
for(int i=1;i<(size-1);++i) {
if (nums[i]<=0 || i > maxLoc) continue; // 如果i位置達不到 或者 i位置沒辦法跳躍
if ((nums[i]+i) >= maxLoc) {
maxLoc = nums[i] + i;
maxLocIndex = i;
}
}
return (size-1) <= maxLoc;
}