《演算法設計與分析》第七週作業
《演算法設計與分析》第七週作業
標籤(空格分隔): 課堂作業
文章目錄
姓名:李**
學號:16340114
題目:Jump Game II(https://leetcode.com/problems/jump-game-ii/description/)
題目概要
初始位置為0。給定一個數列,數列的元素代表當前可以跳躍的最大距離。如果確定可以跳到最後一個元素,問跳到最後的位置最少需要幾步。
思路
很顯然這是一個貪心演算法問題,解題的關鍵就在於怎麼設計貪心策略了。我們每次進行跳躍之後都希望能跳到一個理想的位置,這個位置要距離終點足夠近,並且這個位置能跳躍的最大距離也相對比較大。這樣的話我們跳到一個理想位置之後,距離終點更近了,並且下一次跳躍的位置也有了更多的選擇。只要我們從起點出發,每次都跳到這樣的理想位置上,所用的步數就是最少的了。證明過程(略)
具體實現
我們這樣定義一個理想值:理想值 = 當前位置下標 + 當前位置所能跳躍的最大距離
也就是說理想值是跳到那個位置之後最遠能到達的地方的下標。
先把起點設成當前位置,算出理想值。遍歷理想點所能到達的地方,計算他們的理想值。如果最大的理想值和當前位置的值一樣,那就從當前位置直接跳到其所能到達的最遠位置。如果有除當前位置之外有更大的理想值,那就跳到理想值最大的位置。重複這個操作,直到走到終點。
心得
貪心問題想到了貪心策略就很簡單了,程式設計也不難。在想出這個方法之前我也想過每次走到最遠距離的貪心策略,但這個策略的問題就在於跳到最遠的位置可能會錯過路上更好的位置,比如[3,120,1,…,1],如果一開始就從起點跳3格,就會錯過第二格能跳120格的好位置。
所以我就想著更貪一點,先嚐試跳得最遠,跳完之後還能跳得最遠,於是我的上述的策略就慢慢成型了。認真思考過這個沒有發現這個策略的問題,列舉了幾種情況也還適用,抱著試試的心態交了一波,不出我意料,提交通過了。
感覺貪心演算法就是目前要貪,貪完之後下一步繼續貪,順著這個思路想就對了。找不出反例的話,十有八九是對的~~,證明什麼的就管他呢。~~
原始碼:
class Solution {
public:
int jump(vector<int>& nums)
{
if (nums.size() == 1)
return 0;
int steps = 1;
int currentPosition = 0;
while (currentPosition <= nums.size())
{
if (currentPosition + nums[currentPosition] >= nums.size() - 1)
return steps;
int nextIdealPosition = currentPosition;
int IdealValue = currentPosition + nums[currentPosition];
for (int i = currentPosition + 1; i <= currentPosition + nums[currentPosition]; ++i)
{
if ( i + nums[i] > IdealValue )
{
IdealValue = i + nums[i];
nextIdealPosition = i;
}
}
if (currentPosition == nextIdealPosition)
{
currentPosition = currentPosition + nums[currentPosition];
steps++;
}
else
{
currentPosition = nextIdealPosition;
steps++;
}
}
return 0;
}
};