LeetCode Algorithms 55. Jump Game

題目難度: Medium


原題描述:

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.


題目大意:

        給你一個有非負整數的數組,每一個數代表在這個位置上最多能往前走的步數,假設你現在在數組的第一個位置上,問是否能到達數組的最後一個位置。


解題思路:

        一開始我想到了兩個算法,但都是O(n^2)的。第一個是類似動態規劃的思想,從前往後逐個判斷當前位置能否到達,在判斷能否到達每一個位置的時候需要遍歷從第一個位置到當前位置的前一個位置,看其能否到達當前位置,如果其中有一個可以到達,則當前位置可以到達,這樣一直到最後一個位置就可以得到結果。這裏要注意的是,如果在數組中有一個位置不可到達,則後面的位置也不可能到達,因此可以直接返回false。

      第二個算法是dfs。對於數組中的每一個位置,建立它能夠到達的後面位置的邊,這樣就構造了一個有向無環圖。然後從第一個位置開始dfs,看其是否能到達最後一個位置。dfs的時間複雜度是O(V+E),當邊數很多的時候,E接近V^2,時間複雜度就變成了O(V^2)。

      但是可惜的是,這兩個算法都超時了(dfs棧溢出了),因此這兩個算法都不是最佳的算法。在網上參考了別人O(n)的算法,確實很簡潔,思想簡單卻深刻。算法的思想是:維護一個能到達的最遠位置的reach,對於每一個小於等於reach的位置,如果當前位置能到達的位置大於reach,則更新reach。最後判斷reach大於等於最後一個位置就行了。


時間複雜度分析:

        最後一種算法只需遍歷一次數組,因此時間複雜度爲O(n)。


以下是代碼:

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