算法分析與設計課程作業第六週#1

算法分析與設計課程作業第六週#1

這周學了貪心算法,就在leetcode上根據貪心算法的標籤搜索了道medium題目來做。以下就是題目:

55. Jump Game

Given an array of non-negative integers, you are initially positioned at the first index of the array.
Each element in the array represents your maximum jump length at that position.
Determine if you are able to reach the last index.
For example:
A = [2,3,1,1,4], return true.
A = [3,2,1,0,4], return false. n及擴展

思路

因爲題目的標籤是貪心算法,所以就用貪心的思路去思考問題。那麼怎麼貪心呢?最開始的或者說最容易想到的思路就是從起點開始每跳都走最大步數,然而這樣做的問題是並不能保證能到終點(即本來應返回true卻返回了false),因爲到終點的路徑上的點並非一定恰好是其之前某點的走最大步數能到的點(例如如果要到終點必須經過第二個點,而第一個點最多能跳4步,就把第二個點跳過了),這樣就會丟棄到終點的解,所以不可以。

**第一種思路:**
如果想不丟棄到終點的解(能到終點的就返回true),又想應用貪心算法的思想在每一格都考慮跳最大步數的話,可以考慮從終點開始向前遍歷(能保證不丟棄能到終點的解了),每一格都考慮能跳最大步數,如果該格在其最大步數之內能到達終點,則將其標誌爲新的終點(能到該點就表示能到終點),從解決能否到終點的問題變爲解決能否到該點(在終點之前)的子問題。遍歷完,若標記的終點爲起點,通過遞推就說明從起點能到終點。
該算法時間複雜度爲O(n),空間複雜度爲O(1),應該沒有比該思路更好的方法了。
該思路代碼如下面第一塊(找到思路後實現還是挺簡單的)。

**第二種思路:**
雖然覺得無法做得更好(時間複雜度與空間複雜度上),但與上面的思路時間複雜度與空間複雜度一樣的方法(同樣也是應用貪心算法)還是有的(而且以下算法通常執行時間更短,下面解釋爲什麼):
如果一定要從起點開始,每次依然考慮走最大步,但可以依然分析每個可達最遠點之內的點,考慮每個可達最遠點(而不是走最大步數能到達的點),記錄能到的最遠的點,如果能到的最遠的點大於終點,就表明能到終點。注意我分析的是每個可達最遠點之內的點,而不是分析每個點,如果我分析每個點並持續更新最遠點,這個最遠點並不一定是可達(因爲並不一定每個點都可達),同時分析可達最遠點之內的點保證了不會丟棄能到終點的解(可達最遠點之前的點都是可達的,最遠點之後的點都是不可達的)。從另一個角度來看,從這個方法的思路也可以知道:若一個點可達,則其之前的點均可達。
那麼爲什麼這個算法通常執行時間更短呢,因爲如果要返回false,即算法發現無法抵達終點,通常不需遍歷整個數組,而在遍歷過程的中間即可發現,而第一個算法則無論何時都必須遍歷完整個數組。
該思路代碼如下面第二塊(留意循環其中一個終止條件是:i <= max)。

代碼

第一種思路解決方法

class Solution {
public:
    bool canJump(vector<int>& nums) {
        int lastpos = nums.size() - 1;
        for(int i = lastpos - 1; i >=0; i--){
            if(i + nums[i] >= lastpos){
                lastpos = i;
            }
        }
        return lastpos == 0;
    }
};

第二種思路解決方法

class Solution {
public:
    bool canJump(vector<int>& nums) {
        int lastpos = nums.size() - 1;
        int max = 0;
        for(int i = 0; i <= max && i <= lastpos; i++){
            if(i + nums[i] >= max){
                max = i + nums[i];
            }
        }
        return lastpos <= max;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章