leetcode **45. 跳躍遊戲 II

【題目】**45. 跳躍遊戲 II

給定一個非負整數數組,你最初位於數組的第一個位置。
數組中的每個元素代表你在該位置可以跳躍的最大長度。
你的目標是使用最少的跳躍次數到達數組的最後一個位置。

示例:

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

說明:
假設你總是可以到達數組的最後一個位置。

【解題思路1】從前往後貪心

例如,對於數組 [2,3,1,2,4,2,3],初始位置是下標 0,從下標 0 出發,最遠可到達下標 2。下標 0 可到達的位置中,下標 1 的值是 3,從下標 1 出發可以達到更遠的位置,因此第一步到達下標 1。
從下標 1 出發,最遠可到達下標 4。下標 1 可到達的位置中,下標 4 的值是 4 ,從下標 4 出發可以達到更遠的位置,因此第二步到達下標 4。
維護當前能夠到達的最大下標位置,記爲邊界。從左到右遍歷數組,到達邊界時,更新邊界並將跳躍次數增加 1。
在遍歷數組時,不訪問最後一個元素,這是因爲在訪問最後一個元素之前,邊界一定大於等於最後一個位置,否則就無法跳到最後一個位置了。如果訪問最後一個元素,在邊界正好爲最後一個位置的情況下,會增加一次「不必要的跳躍次數」,因此不必訪問最後一個元素。

class Solution {
    public int jump(int[] nums) {
        int len = nums.length - 1;
        int now = 0, end = 0;
        int maxPosition = 0; 
        int steps = 0;
        while(end < len){
            maxPosition = Math.max(maxPosition, now + nums[now]);  //維護臨時可到達的最遠位置
            if(now == end){ //end是最遠可達邊界,到達邊界時,更新邊界並將跳躍次數增加1
                end = maxPosition; //end更新爲在上一個跳躍點可達範圍內可以跳躍到最遠位置
                steps++; //達到局部最優選擇效果
            }
            now++;
        }
        return steps;
    }
}

【解題思路2】反向貪心

考慮到達數組的最後一個位置前,最後一步跳躍前所在的位置,該位置通過跳躍能夠到達最後一個位置。
可能有多個位置通過跳躍都能夠到達最後一個位置,可以「貪心」地選擇距離最後一個位置最遠的那個位置,也就是對應下標最小的那個位置。因此,可以從左到右遍歷數組,選擇第一個滿足要求的位置。
找到最後一步跳躍前所在的位置之後,我們繼續貪心地尋找倒數第二步跳躍前所在的位置,以此類推,直到找到數組的開始位置。

class Solution {
    public int jump(int[] nums) {
        int position = nums.length - 1;
        int steps = 0;
        while (position > 0) {
            for (int i = 0; i < position; i++) {
                if (i + nums[i] >= position) { //找到可到達position的最遠的位置
                    position = i;
                    steps++;
                    break;
                }
            }
        }
        return steps;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章