【LeetCode】LeetCode之跳跃游戏——动态规划+贪心算法
| 【LeetCode】LeetCode之打家劫舍Ⅱ——暴力遞歸+動態規劃解決循環問題+DP空間優化 | https://blog.csdn.net/Kevinnsm/article/details/121813241?spm=1001.2014.3001.5501 |
| 【LeetCode】LeetCode之刪除并獲得點數——動態規劃、排序+動態規劃 | https://blog.csdn.net/Kevinnsm/article/details/121838892?spm=1001.2014.3001.5501 |
1.題目描述
給定一個非負整數數組 nums ,你最初位于數組的 第一個下標 。
數組中的每個元素代表你在該位置可以跳躍的最大長度。
判斷你是否能夠到達最后一個下標。(nums.length>0)
🥩示例 1:
輸入:nums = [2,3,1,1,4]
輸出:true
解釋:可以先跳 1 步,從下標 0 到達下標 1, 然后再從下標 1 跳 3 步到達最后一個下標。
🥩示例 2:
輸入:nums = [3,2,1,0,4]
輸出:false
解釋:無論怎樣,總會到達下標為 3 的位置。但該下標的最大跳躍長度是 0 , 所以永遠不可能到達最后一個下標。
2.思路分析
這種問題首先能夠想到的肯定是能否使用動態規劃,不要問為什么,問就說做的多了。
首先做動態規劃這一類的題,首先要考慮的是如何將原分解成一個個的小問題。
例如上述n=8的一個nums數組,分析流程如下:
- Ⅰ.如果我要求f(8)【8號位置是不是可達的】,是不是我只需要判斷f(7)是否是可達以及f(7)+7 >= 8【f(7)>=1】;
- Ⅱ.對于Ⅰ中我們核心要求f(7)是否可達,是不是意味著只需要判斷f(6)是否可達以及f(6)+6 >= 7,也就是f(6)>=1.
所以該子問題分解成功!此時狀態轉移方程也就推導出來了。【下圖0也可達,寫錯了!】
3.動態規劃解題代碼及其分析
public boolean canJump2(int[] nums) {if (nums.length == 1) {return true;}boolean[] dp = new boolean[nums.length];dp[0] = true;for (int i = 1; i < nums.length; i++) {for (int j = 0; j < i; j++) {if (dp[j] && nums[j] + j >= i) {dp[i] = true;break;}}}return dp[nums.length - 1];}提交到LeetCode時,發現執行時間高達772ms。
復雜度分析
時間復雜度:O(n^2)
空間復雜度:O(n)
4.貪心思路分析
在上述動態規劃的分析中,我們會發現使用動態規劃無法達到比較好的效果。因為動態規劃的解要依賴子問題的解,仔細想一下你就會發現本題中有可能某個數據會一步到達最后,也就是可以進行跳躍。
所以我們可以利用貪心思想,對數組進行遍歷,在這個遍歷過程中維護一個最遠距離;一旦這個最遠距離大于nums.length-1,直接返回true即可。
代碼實現
public boolean canJump4(int[] nums) {int size = nums.length;int maxFar = nums[0];for (int i = 0; i < size; i++) {if (maxFar >= i) {maxFar = Math.max(maxFar, nums[i] + i);if (maxFar >= size - 1) {return true;}}}return false;}當我提交到LeetCode時如圖所示。
復雜度分析
時間復雜度:O(n)
空間復雜度:O(1)
相比較使用時動態規劃有了巨大的提升。
總結
以上是生活随笔為你收集整理的【LeetCode】LeetCode之跳跃游戏——动态规划+贪心算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【LeetCode】LeetCode之删
- 下一篇: 【LeetCode】LeetCode之跳