跳躍遊戲(jump-game)
給定一個非負整數數組,你最初位於數組的第一個位置。
數組中的每個元素代表你在該位置可以跳躍的最大長度。
判斷你是否能夠到達最後一個位置。
示例 1:
輸入: [2,3,1,1,4]
輸出: true
解釋: 從位置 0 到 1 跳 1 步, 然後跳 3 步到達最後一個位置。
示例 2:
輸入: [3,2,1,0,4]
輸出: false
解釋: 無論怎樣,你總會到達索引爲 3 的位置。
但該位置的最大跳躍長度是 0 , 所以你永遠不可能到達最後一個位置。
思路
從第 i 位置最遠可以跳 nums[ i ] 步。
比如[2,3,1,1,4]
從0位置,最遠可以跳兩步;
從1位置,最遠可以跳三步;
從2位置,最遠可以跳一步;
從3位置,最遠可以跳一步;
…
這樣子無法直接看出規律,我們把最遠跳多少步轉化爲可以跳躍到的位置。
我們把數組豎起來看一下規律。
數組 | 位置 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
---|---|---|---|---|---|---|---|---|---|---|
2 | 0 | O | O | |||||||
3 | 1 | O | O | O | ||||||
1 | 2 | O | ||||||||
1 | 3 | O | ||||||||
4 | 4 | O | O | O | O |
從上面的表格可以看出
從第0位置,可以跳躍第1位置或第2位置;
從第1位置,可以跳躍第2、第3、第4位置;
從第2位置,可以跳躍第3位置;
從第3位置,可以跳躍第4位置;
…
所以,發現規律,從第 i 位置,最遠可以跳至第 index[ i ] 位置。
i + nums[ i ] = index[ i ]。
代碼
#include <stdio.h>
#include <vector>
class Solution {
public:
bool canJump(std::vector<int>& nums) {
std::vector<int> index; //最遠可跳至的位置
for (int i = 0; i < nums.size(); i++){
index.push_back(i + nums[i]);//計算index數組
}
int jump = 0; //jump指針
int max_index = index[0]; //最遠可以跳到的位置
while(jump < index.size() && jump <= max_index){
if (max_index < index[jump]){
max_index = index[jump]; //如果可以跳得更遠,則更新max_index
}
jump++; //掃描jump
}
if (jump == index.size()){ //若jump到達數組尾部則返回真
return true;
}
return false; //否則返回假
}
};
int main(){
std::vector<int> nums;
nums.push_back(2);
nums.push_back(3);
nums.push_back(1);
nums.push_back(1);
nums.push_back(4);
Solution solve;
printf("%d\n", solve.canJump(nums));
return 0;
}
java
public class Solution {
public boolean canJump(int[] nums) {
int n = nums.length;
int rightmost = 0;
for (int i = 0; i < n; ++i) {
if (i <= rightmost) {
rightmost = Math.max(rightmost, i + nums[i]);
if (rightmost >= n - 1) {
return true;
}
}
}
return false;
}
}
python3
class Solution:
def canJump(self, nums: List[int]) -> bool:
n, rightmost = len(nums), 0
for i in range(n):
if i <= rightmost:
rightmost = max(rightmost, i + nums[i])
if rightmost >= n - 1:
return True
return False