目录
讀題
122.买卖股票的最佳时机II
自己看到题目的第一想法
看到這個題目我就想到最大子序和以及擺動序列,最大子序和讓我了解到尋求最大子序和的做法,以及如果是小於零我則捨棄掉之前的結果,重新開始,然後擺動序列是讓我在有波動時,就是preMax > curMax時在初始化變數值。也因此我思考了下,稍微去模擬後就寫出來了,但不知道是不是貪心算法的緣故,解的很虛阿。
55. 跳跃游戏
自己看到题目的第一想法
element代表可以跳得最遠距離,但不代表說不能跳小於這個步數的,首先想到兩個部分分別是
if(nums[0] > nums.size()) return true;
if(nums[0] == 0) return false;
之後想到的是,每次都是由nums[0],所開始跳躍,是要使用遞迴來解決嗎?
實在想不了解解法,直接看
看完代码随想录之后的想法
實在很巧妙,局部最優是遍歷元素時,每次都取最大的覆蓋範圍,在局部最優堆疊到全局最優,這樣思考起來的確很簡單,我剛剛的想法就會比較像是要去思考跳幾步,從思考跳幾步變成思考最大覆蓋範圍。
45.跳跃游戏II
自己看到题目的第一想法
我看到的想法是局部最優是,從0開始,每次都找我的覆蓋範圍內最大的數值跳躍過去
看完代码随想录之后的想法
看完之後跟我的整體思路有些類似,但我實際代碼還需要進行調整,還需要多看幾次。
122.买卖股票的最佳时机II 實作
思路
- 建立preMax、curMax以及result;
- 建立for循環,i從1開始持續加加,j初始為零 → 可以想像j為買入時間,i為賣出時間
- 今天的max,假設今日賣出的價值大於昨日賣出,則更新昨日賣出的樹值
- 假設今日賣出的價格小於昨日賣出,則將preMax加到result當中,並且將curMax以及preMax初始為零,j = i; 可以想像說昨日賣出比較好,所以result 加上preMax,preMax = 0代表已經賣出,j = i 代表今日買入。
- 假設有一段每天都比昨天賣好一點直到最後,那就遍歷結束後,preMax如果大於0,則把preMax加給result,確保結果確實存入
局部最優: 最大和 + nums[i],最大和必須比之前好,如果沒有比之前好,則應該在最大和時賣出。
Code
class Solution {
public:
int maxProfit(vector<int>& prices) {
int preMax = 0;
int curMax = 0;
int result = 0;
for(int j = 0, i = 1; i < prices.size(); i++) {
curMax = prices[i] - prices[j];
if(curMax > preMax) preMax = curMax;
if(preMax > curMax) {
result += preMax;
preMax = 0;
j = i;
}
}
if(preMax > 0) result += preMax;
return result;
}
};
55. 跳跃游戏 - 實作
思路
- 建立cover,初始為0
- 假設當前跳躍的步數+當下跳躍到的nums[i]中的值, 大於最大覆蓋範圍,那就更新cover
- 假設cover >= nums.size() - 1 代表一定可以跳到最後一個元素, return true;
- 如果遍歷完都沒有可以覆蓋到最後一個元素的,return false;
Code
class Solution {
public:
bool canJump(vector<int>& nums) {
int cover = 0;
for(int i = 0; i <= cover; i++) {
cover = max(i+nums[i], cover);
if(cover >= nums.size() - 1) return true;
}
return false;
}
};
45.跳跃游戏II - 實作
思路
- 局部最優是,從0開始,每次都找我的覆蓋範圍內最大的數值跳躍過去
錯誤點,應該是要讓i 逐步走,除非走到當前可以走到的最遠距離在更新next。
Code
錯誤代碼
class Solution {
public:
int jump(vector<int>& nums) {
if(nums.size() == 1) return 0;
int cover = 0;
int result = 0;
for(int i = 0; i <= cover;) {
if(i + nums[i] >= cover) {
cover = cover+nums[i];
result++;
}
if(cover > nums.size() - 1) return result;
int max = 0;
for(int j = i; j <= cover; j++) {
if(nums[j] >= max) {
max = nums[j];
i = j;
}
}
}
return result;
}
};
正確代碼
class Solution {
public:
int jump(vector<int>& nums) {
int curMax = 0;
int result = 0;
int nextMax = 0;
for (int i = 0; i < nums.size() - 1; i++) {
nextMax = max(nums[i] + i, nextMax);
if (i == curMax) {
curMax = nextMax;
result++;
}
}
return result;
}
};
總結
自己实现过程中遇到哪些困难
看完之後,對於貪心算法的思路,真的很挑戰自己的常識性思維,有時需要用很不同的角度去看問題才能找到解法,如果沒有這樣做,很可能會整個亂掉。
今日收获,记录一下自己的学习时长
今天大概學習了兩小時左右,整體還是覺得貪心算法很活,自己還需要多訓練用不同的角度看問題才行。
相關資料
● 今日学习的文章链接和视频链接
122.买卖股票的最佳时机II
https://programmercarl.com/0122.买卖股票的最佳时机II.html
55. 跳跃游戏
https://programmercarl.com/0055.跳跃游戏.html
45.跳跃游戏II