題目鏈接
LeetCode 55. 跳躍遊戲[1]
題目描述
給定一個非負整數數組,你最初位於數組的第一個位置。
數組中的每個元素代表你在該位置可以跳躍的最大長度。
判斷你是否能夠到達最後一個位置。
示例1
輸入:
[2,3,1,1,4]
輸出:
true
解釋:
我們可以先跳 1 步,從位置 0 到達 位置 1, 然後再從位置 1 跳 3 步到達最後一個位置。
示例2
輸入:
[3,2,1,0,4]
輸出:
false
解釋:
無論怎樣,你總會到達索引爲 3 的位置。但該位置的最大跳躍長度是 0 , 所以你永遠不可能到達最後一個位置。
題解
動態規劃+正推
用 表示位置 是否可達,初始的時候都是 ,只有 ,因爲起點一定是可達的。
然後從位置 開始遍歷。對於位置 ,如果發現 ,那麼從前面的位置無法到達它,那麼就更無法到達後面的位置了,所以直接返回 false
。
否則的話,它能到達的範圍是 到 ,所以把這部分的 值都標記爲 。
如果發現 ,就說明當前位置直接就能跳到終點了,直接返回 true
。
時間複雜度 ,空間複雜度 。
動態規劃+倒推
用 表示從位置 能否到達終點,初始的時候都是 ,只有 ,因爲從終點一定是可到達終點的。
然後從位置 開始往前遍歷。對於位置 ,如果 ,那就說明當前位置直接就可以到達終點,那麼就令 。
否則的話遍歷所有的 到 ,如果其中有等於 的,那就說明先跳到那個位置,就能再跳到終點了。一個都沒有的話 。
最後看 是否爲 就行了。
時間複雜度 ,空間複雜度 。
貪心+正推
在上面的動態規劃方法中,對於位置 ,我們需要把他能到達的位置全部做上標記。
但是其實沒有必要這麼做,只需要記錄一下能到的最遠的那個位置 就行了。如果遍歷之後的位置 時,發現 ,那就說明之前的所有位置最遠都無法到達 ,那就直接返回 false
。否則的話,比較一下當前能到達的最遠位置,更新一下 的值。
時間複雜度 ,空間複雜度 。
貪心+倒推
還是從上面的動態規劃方法改變來的,上面動態規劃在位置 ,需要遍歷所有它能到達的位置,然後看有沒有位置能夠到達終點。
其實只需要看能到的最遠的那個位置就行了,我們用 表示後面的位置中最靠前的那個能夠到達終點的位置。如果最遠到達位置滿足 ,那就說明位置 可以直接跳到 ,那麼就更新 。否則的話怎麼跳都跳不到終點,因爲 和 之間的位置都是無法到達終點的。
需要注意的是,這裏最遠的位置 不一定能到達終點哦,但是中間的某個位置可能能夠達到。
時間複雜度 ,空間複雜度 。
代碼
動態規劃+正推(c++)
class Solution {
public:
bool canJump(vector<int>& nums) {
int n = nums.size();
vector<int> dp(n, 0);
dp[0] = 1;
for (int i = 0; i < n; ++i) {
if (!dp[i]) return false;
if (i+nums[i] >= n-1) return true;
for (int j = i+1; j <= i+nums[i]; ++j) {
dp[j] = 1;
}
}
return false;
}
};
動態規劃+倒推(c++)
class Solution {
public:
bool canJump(vector<int>& nums) {
int n = nums.size();
vector<int> dp(n, 0);
dp[n-1] = 1;
for (int i = n-2; i >= 0; --i) {
if (i+nums[i] >= n-1) {
dp[i] = 1;
continue;
}
for (int j = i+1; j <= i+nums[i]; ++j) {
dp[i] |= dp[j];
if (dp[i]) break;
}
}
return dp[0];
}
};
貪心+正推(c++)
class Solution {
public:
bool canJump(vector<int>& nums) {
int n = nums.size(), maxx = 0;
for (int i = 0; i < n; ++i) {
if (i > maxx) return false;
maxx = max(maxx, i+nums[i]);
}
return maxx >= n-1;
}
};
貪心+倒推(c++)
class Solution {
public:
bool canJump(vector<int>& nums) {
int n = nums.size(), minn = n-1;
for (int i = n-2; i >= 0; --i) {
if (i+nums[i] >= minn) minn = i;
}
return !minn;
}
};
參考資料
[1]
LeetCode 55. 跳躍遊戲: https://leetcode-cn.com/problems/jump-game/