[Leedcode][JAVA][第55题][跳跃游戏][贪心][动态规划]
【問題描述】
給定一個非負整數數組,你最初位于數組的第一個位置。數組中的每個元素代表你在該位置可以跳躍的最大長度。判斷你是否能夠到達最后一個位置。示例?1:輸入: [2,3,1,1,4] 輸出: true 解釋: 我們可以先跳 1 步,從位置 0 到達 位置 1, 然后再從位置 1 跳 3 步到達最后一個位置。 示例?2:輸入: [3,2,1,0,4] 輸出: false 解釋: 無論怎樣,你總會到達索引為 3 的位置。但該位置的最大跳躍長度是 0 , 所以你永遠不可能到達最后一個位置。【解答思路】
1. 正向貪心
時間復雜度:O(N) 空間復雜度是O(1)
public boolean canJump(int[] nums) {if (nums == null || nums.length == 0) return true;int maxDist = 0;int n = nums.length;for (int i = 0; i < n; i++) {// 到不了該位置,提前終止if (maxDist < i) return false;// 可以到達末尾位置,提前終止if (maxDist >= n - 1) return true;// 更新可以到達的最遠距離maxDist = Math.max(maxDist, nums[i] + i); }return false;}2. 反向貪心
以[2, 3, 1, 1, 4]為例,我們的目標是到達最后一個位置。
1、因為倒數第二個位置為1,所以從倒數第二個位置可以到達最后一個位置。因此只要我們能到達倒數第二個位置就能到達最后一個位置。
2、因為倒數第三個位置為1,所以從倒數第三個位置可以到達倒數第二個位置。因此只要我們能到達倒數第三個位置就能到達倒數第二個位置從而能到達最后一個位置。
3、因為倒數第四個位置為3,所以從倒數第四個位置可以到達倒數第三個位置。因此只要我們能到達倒數第四個位置就能到達倒數第三個位置從而能到達最后一個位置。
4、因為倒數第五個位置為2,所以從倒數第五個位置可以到達倒數第四個位置。因此只要我們能到達倒數第五個位置(也就是第一個位置)就能到達倒數第三個位置從而能到達最后一個位置。
因此,可以到達最后一個位置。
- 用一個變量pos來表示需要到達的位置,并初始化為nums.length - 1表示需要到達的位置為最后一個位置。
- 從nums.length - 2向前遍歷,if(nums[i] + i >= pos)表示從當前位置出發能夠到達pos,到達當前位置i就可以到達pos,更新pos為i的值。
- 遍歷到最后如果pos==0,也就表示從開始能夠跳到末尾。
時間復雜度:O(N) 空間復雜度是O(1)
public boolean canJump(int[] nums) {if (nums == null || nums.length == 0) {return false;}//pos表示需要到達的位置int pos = nums.length - 1;for (int i = nums.length - 2; i >= 0; i--) {if (nums[i] + i >= pos) {pos = i;}}return pos == 0;}3.動態規劃
我們新建一個boolean[] dp來表示能否到達該位置。初始化dp[0]=true,此時dp為[true,false,false,false,false]。
以nums = [2, 3, 1, 1, 4]為例,
1、dp[0] = true, nums[0] = 2, 因此往后推兩個位置也可到達,此時dp為[true,true,true,false,false]。
2、dp[1] = true, nums[1] = 3, 因此往后推兩個位置也可到達,此時dp為[true,true,true,true,true]。
此時dp[4] = true,其實已經可以表示能到達末尾了。這種表示方法在下面的代碼中用表示一
3、dp[2] = true, nums[2] = 1, 因此往后推一個位置也可到達,此時dp為[true,true,true,true,true]。
4、dp[3] = true, nums[3] = 1, 因此往后推一個位置也可到達,此時dp為[true,true,true,true,true]。
此種方式用方式二表示
時間復雜度是O(N^2),空間復雜度是O(N)
【總結】
1. 動態or貪心
-如果使用動態規劃,dp[i]代表能否跳到第i個格子的話,那么dp[i]本身沒有辦法很好地從dp[j](j < i)中得到,因為不知道有哪些格子可以跳到該點,因此動態規劃的解法可能就沒有那么優了。
-如果使用貪心(貪心是每個狀態只使用一次的動態規劃),是因為判斷一個格子是否能到達,其實只要看這個格子是否在當前的可到達的區間內即可——而維護一個區間要比維護一個dp數組簡單得多,況且區間的左端必然是0,那么只需要維護右端即可了~
2.思路方向找準 塊狀思考 邊界終止條件多樣化 想好再下手
3.Missing return statement” within if / for / while
if, while 或 for 里面的return 有可能不執行,編譯器將強制您添加return語句
除非使用if-else結構
參考鏈接:https://leetcode-cn.com/problems/jump-game/solution/shun-zhao-tui-dao-zhao-tui-liang-chong-fang-shi-ji/
總結
以上是生活随笔為你收集整理的[Leedcode][JAVA][第55题][跳跃游戏][贪心][动态规划]的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 晶科电力打造山东省最大物流港分布式光伏项
- 下一篇: GeoMAN:多层Attention网络