【LeetCode 45 55 1306】Jump Game I,II,III【JAVA】

跳躍遊戲,合計三道題。

55. Jump Game

1. 題目

在這裏插入圖片描述

2. 思路

這道題即考慮是否達到最後的一個位置,我們可以通過到達每一個下標處時,維護一個可達最大下標值,判斷我們能否到達數組的最後一個下標。

3. 代碼

    public boolean canJump(int[] nums) {
        int maxIndex = 0;
        for (int i = 0; i < nums.length; i++) {
            // 可達最大下標值大於當前遍歷的下標值,則說明該下標無法被到達
            if (maxIndex < i) {
                return false;
            }

            // 更新可達最大下標值
            maxIndex = Math.max(maxIndex, i + nums[i]);

            // 可達最大下標值不小於數組最大下標值,則說明可以到達最後一個位置
            if (maxIndex >= nums.length - 1) {
                return true;
            }
        }

        return false;
    }

4. 運行結果

在這裏插入圖片描述

45. Jump Game II

1. 題目

在這裏插入圖片描述

2. 方法一

2.1 思路

該題目與上一道題的區別在於這個是求最少幾次可以到達,一個比較笨的方法是,我們可以維護一個數組來記錄到達每一個下標的最少次數,從頭往後遍歷每一個下標,更新從該下標能到達的位置的最少次數,最終來算出數組最後一個位置最少幾次可以到達。該思路需要一個額外的數組,空間複雜度爲o(n),而時間上,需要從頭到尾遍歷一次,同時每個節點又需要更新其能到達的下標位置的值,因此時間複雜度爲O(n²)

2.2 代碼

   public int jump(int[] nums) {
        int[] dp = new int[nums.length];
        for (int i = 1; i < nums.length; i++) {
            dp[i] = Integer.MAX_VALUE;
        }

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

        return dp[nums.length - 1];
    }

2.3 運行結果

在這裏插入圖片描述

3. 方法二

3.1 思路

上面的方法一思路簡單,但是時間複雜度比較高,我們考慮其他做法。
我們可以聯想Jump Game的第一題,第一題是問我們能否到達最後一個下標,即我們其實也是求了我們能到達最大下標處,那我們是不是也可以將這道題這麼考慮:我們需要求出最少幾步才能到達數組的末尾,即我們可以通過求第n步最遠能到達哪裏來進行判斷,即思路變爲求每增加一步時,我們可以到達的下標位置是多少,是否已經到達了數組的末尾。這種思路只需要遍歷一次數組,空間複雜度爲O(n)。

3.2 代碼

    public int jump1(int[] nums) {
        // 跳躍的步數
        int steps = 0;
        // 當前步數可到達的最大下標
        int maxIndex = 0;
        // 增加一步可以到達的最大下標
        int nextIndex = nums[0];
        
        for (int i = 0; i < nums.length; i++) {
            // 當前遍歷的下標值已經超過了當前步數可達的最大下標
            if (i > maxIndex) {
                steps++;
                if (nextIndex >= nums.length - 1) {
                    break;
                } else {
                    maxIndex = nextIndex;
                }
            }

            // 更新下一步能到達最大下標
            nextIndex = Math.max(nextIndex, i + nums[i]);
        }

        return steps;
    }

3.3 運行結果

可以看到所需時間遠遠小於方法一。

在這裏插入圖片描述

1306. Jump Game III

1. 題目

在這裏插入圖片描述

2. 思路

這道題比較有意思,判斷的是從數組的某個下標開始,能否最終到達元素值爲0的下標處。這種題目,很容易聯想到遞歸的思路。

3. 代碼

    private HashSet<Integer> set = new HashSet<>();

    public boolean canReach(int[] arr, int index) {
        // set中已有該下標,則說明出現循環,退出
        if (index < 0 || index > arr.length - 1 || set.contains(index)) {
            return false;
        }

        set.add(index);
        // 判斷該點是否爲下標值爲0的地方,或者index + arr[index]跟index - arr[index] 是否爲下標值爲0的地方
        if (arr[index] == 0 || canReach(arr, index + arr[index]) || canReach(arr, index - arr[index])) {
            return true;
        }
        set.remove(index);
        return false;
    }

4. 運行結果

在這裏插入圖片描述

相關鏈接

本題代碼的github鏈接 —— 55. Jump Game
本題代碼的github鏈接 —— 45. Jump Game II
本題代碼的github鏈接 —— 1306. Jump Game III
其他 LeetCode 題目
LeetCode Top 100 Liked Questions 題目

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章