1. 程式人生 > 其它 >[LeetCode] #45 跳躍遊戲 II

[LeetCode] #45 跳躍遊戲 II

[LeetCode] #45 跳躍遊戲 II

給你一個非負整數陣列 nums ,你最初位於陣列的第一個位置。

陣列中的每個元素代表你在該位置可以跳躍的最大長度。

你的目標是使用最少的跳躍次數到達陣列的最後一個位置。

假設你總是可以到達陣列的最後一個位置。

輸入: nums = [2,3,1,1,4]
輸出: 2
解釋: 跳到最後一個位置的最小跳躍數是 2。
從下標為 0 跳到下標為 1 的位置,跳 1 步,然後跳 3 步到達陣列的最後一個位置。

使用最少的跳躍次數很容易可以想到用貪心演算法或者動態規劃

貪心演算法有兩種思路

一是貪開始的每一步,二是貪最後一步

貪心演算法一(貪開始的每一步)

以[2,3,1,1,4]為例,

位於0下標位置,可以選擇到1下標、2下標,最遠邊界是2(max= 2

此時必須跳一步(step++,step=1),最遠可以跳到2,當我們到達2時又必須選擇跳下一步(end= 2

位於1下標位置,可以選擇到2下標、3下標、4下標,最遠邊界是4(max= 4

此時可以先不跳

位於2下標位置,可以選擇到3下標,最遠邊界是3,小於4不更新邊界

此時必須跳一步(step++,step=2),最遠可以跳到4,當我們到達4時又必須選擇跳下一步(end= 4)

。。。。。

class Solution {
    public int jump(int[] nums) {
        int l = nums.length;
        int end = 0;
        
int max = 0; int step = 0; for(int i = 0; i < l - 1; i++){ max = Math.max(max, nums[i] + i); if(i == end){ end = max; step++; } } return step; } }

貪心演算法二(貪最後一步)

以[2,3,1,1,4]為例,

位於0下標位置,顯然不能跳到最後,不能最為最後一步

位於1下標位置,可以跳到最後,此時與終點最遠,直接貪,作為最後一步。確認這一步(step++)之後,更新最後一步(last=i)並且重新開始(break)。

。。。。

當最後一步是起點時結束

class Solution {
    public int jump(int[] nums) {
        int step = 0;
        int last = nums.length - 1;
        while(last > 0){
            for(int i = 0; i < last; i++){
                if(nums[i] + i >= last){
                    last = i;
                    step++;
                    break;
                }
            }
        }
        return step;
    }
}

動態規劃

dp[i]:到達i的最小步數

狀態轉移方程:dp[i + j] = Math.min(dp[i + j], dp[i] + 1)

class Solution {
    public int jump(int[] nums) {
        int[] dp = new int[nums.length];

        dp[0] = 0;
        for (int i = 1; i < dp.length; i++) {
            dp[i] = nums.length + 1;
        }

        for (int i = 0; i < nums.length; i++) {
            for (int j = 1; j <= nums[i]; j++ ) {
                if (i + j >= nums.length) {
                    return dp[dp.length - 1];
                }
                dp[i + j] = Math.min(dp[i + j], dp[i] + 1); 
            }
        }

        return dp[dp.length - 1];
    }
}

知識點:

總結: