[Leetcode]Jump Game && Jump Game II

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.

這道題拿過來就“呵呵”了兩次,一次用的遞歸timeout,一次用的DP又是timeout。這裏倒不是說DP不能用,可能是我的DP寫的效率太低了。最後用貪心實現了算法。(話說貪心和DP有千絲萬縷的聯繫啊,爲什麼DP不行呢?唉...)

這裏從第一步開始,都用一個量farest存儲當前所能到達的最遠處,貪心選擇就是:如果當前位置i+A[i]>farest更新farest,直到farest>=n-1結束。

然後考慮失敗的情況,失敗的前提肯定是第i個數組元素爲零,並且前i-1個元素所能到達的最遠位置就是i,那麼遊戲結束,返回false。

上代碼:

class Solution{
public:
	bool canJump(int A[], int n) {
		int farest = 0;
		for (int i = 0; i < n; i++){
			if (i == farest && A[i] == 0) break;
			if (A[i] + i > farest){
				farest = A[i] + i;
			}
			if (farest >= n - 1)
				return true;
		}
		if (farest == n - 1) return true;
		else return false;
	}
};

後來在網上翻了一下別人的做法,還有另一種貪心的實現方式,就是用一個量來記錄當前位置可跳的最大步數。

從maxstep =  A[0]開始,當i=1時,maxstep--,然後和A[1]比較,不斷更新maxstep,直到遊戲結束。

class Solution {  
public:  
    bool canJump(int A[], int n) {  
        if(n==0||n==1){  
            return true;  
        }  
        int maxstep=A[0];  
        for(int i=1;i<n;i++){  
            if(maxstep==0) return false;  
            maxstep--;  
            if(maxstep<A[i]){  
                maxstep=A[i];  
            }  
            if(maxstep+i>=n-1){  
                return true;  
            }  
        }  
    }  
}; 

再看第二題

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.

Your goal is to reach the last index in the minimum number of jumps.

For example:
Given array A = [2,3,1,1,4]

The minimum number of jumps to reach the last index is 2. (Jump 1 step from index 0 to 1, then 3 steps to the last index.)

這一題是要找到到達n的最小步數。這裏仍然使用貪心的思想,在第一題的基礎上,記錄每一步可以到達的最遠距離。

例如第一步,可到達的最遠距離是A[0],這是還沒到達n,所以就要再走第二步,那麼就在1-A[i]之間,找到可以到達最遠距離的第二步,作爲第二步,局部最佳就是全局最佳,最後得到最小步數。

class Solution {
public:
	int jump(int A[], int n) {
		if (0 == n || 1 == n || A[0] == 0) return 0;
		if (A[0] >= n-1) return 1;
		return nextStep(0, A[0], n, 1, A);
	}
	int nextStep(int start, int end, int n, int steps,int A[]){
		int newEnd = end;
		int newStart;
		for (int i = start; i <= end; i++){
			if (i + A[i] > newEnd){
				newEnd = i + A[i];
				newStart = i;
			}
			if (newEnd >= n - 1)
				return ++steps;
		}
		return nextStep(newStart, newEnd, n, ++steps, A);
	}
};
下面來一個非遞歸的實現:

用last記錄上一步到達過的最遠距離,只要i超過這個位置,step就得加一,並且更新last的值。

class Solution {  
public:  
    int jump(int A[], int n) {  
        int ret = 0;//當前跳數  
        int last = 0;//上一跳可達最遠距離  
        int curr = 0;//當前一跳可達最遠距  
        for (int i = 0; i < n; ++i) {  
            if(i>curr){  
                return -1;  
            }  
            if (i > last) {  
                last = curr;  
                ++ret;  
            }   
            curr = max(curr, i+A[i]);  
        }  
  
        return ret;  
    }  
}; 





發佈了35 篇原創文章 · 獲贊 1 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章