首先祝大家五四青年節快樂!!!好好讀書,長大掙錢
問題描述:
給定一個非負整數數組,你最初位於數組的第一個位置。
數組中的每個元素代表你在該位置可以跳躍的最大長度。
你的目標是使用最少的跳躍次數到達數組的最後一個位置。
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/jump-game-ii
例:
輸入: [2,3,1,1,4]
輸出: 2
解釋: 跳到最後一個位置的最小跳躍數是 2。
從下標爲 0 跳到下標爲 1 的位置,跳 1 步,然後跳 3 步到達數組的最後一個位置。
說明:
假設你總是可以到達數組的最後一個位置。
解題思路:
首先看到這題,其實最先想到的是動態規劃,
記 dp[i] 爲從座標 i 跳到終點的最小步數, 則 dp[i] = min(dp[i+1]], dp[i+2]... dp[i+num[i]]) + 1
所求爲dp[0]
int count = nums.size();
//if(nums[0]==25000)return 2;
int dp[count];
fill(dp,dp+count,count+1);
dp[count-1] = 0;
for(int i=count-2; i>=0; --i) {
int max_length = nums[i];
int min_step = count;
for (int j=1;j<=max_length && i+j<count;++j) {
min_step = min(min_step, dp[i+j]+1);
}
dp[i] = min_step;
}
return dp[0];
這裏有個測試用例過不了,我在評論區看到大佬這樣加上註釋那一行,真是面向測試編程,哈哈哈哈哈
後來看到官方解答,發現這是一道標準的貪心算法
每個步驟都有自己可以行動的範圍。在當前步驟的行動範圍內,選擇下一個步驟的最大行動範圍,直到下一個步驟覆蓋終點。
int end=0;
int max_pos = 0;
int res=0;
for(int i=0;i<nums.size()-1;i++){
if(max_pos>=i) max_pos = max(max_pos,i+nums[i]);
if(end == i){
end = max_pos;
res++;
}
}
return res;
在具體的實現中,我們維護當前能夠到達的最大下標位置,記爲邊界。我們從左到右遍歷數組,到達邊界時,更新邊界並將跳躍次數增加 1。
在遍歷數組時,我們不訪問最後一個元素,這是因爲在訪問最後一個元素之前,我們的邊界一定大於等於最後一個位置,否則就無法跳到最後一個位置了。
if(nums.size()==1) return 0;
int end=0;
int max_pos = 0;
int res=0;
for(int i=0;i<nums.size()-1;i++){
if(max_pos>=i) max_pos = max(max_pos,i+nums[i]);
if(end == i){
end = max_pos;
res++;
}
}
return res;