貪心|122.買賣股票的最佳時機II、55.跳躍游戲、45.跳躍游戲II
122.買賣股票的最佳時機II
思路
局部最優:收集每天的正利潤,全局最優:求得最大利潤。
利潤分解
代碼:
class Solution {
public:
int maxProfit(vector<int>& prices) {
int ans = 0;
for(int i = 0; i < prices.size() - 1; i++){
int price = prices[i + 1] - prices[i];
ans += max(price, 0);
}
return ans;
}
};
參考詳解
55.跳躍游戲
思路
貪心算法局部最優解:每次取最大跳躍步數(取最大覆蓋范圍),整體最優解:最后得到整體最大覆蓋范圍,看是否能到終點。
代碼:
class Solution {
public:
bool canJump(vector<int>& nums) {
int cover = 0;
if(nums.size() == 1) return true;
for(int i = 0; i <= cover; i++){
cover = max(nums[i] + i, cover);
if (cover >= nums.size() - 1) {
return true;
}
}
return false;
}
};
參考詳解
45.跳躍游戲II
思路
首先 起始位置為0,覆蓋范圍為零。然后遍歷目前的數組,因為本題目一定有解,所以我們記錄在目前的覆蓋范圍內最大的可跳躍值(在目前跳躍范圍中我們最遠可以到達的值)這個值是目前遍歷的index加該index所對應的數組的值
(nums[i] + i)
。當遍歷到當前覆蓋范圍的末尾,我們首先發現覆蓋范圍小于數組長度,說明我們需要再跳躍一步,而且我們已經收集到了目前跳躍范圍內,能跳躍到的最大位置。此時given我們需要再跳躍一步,我們要更新覆蓋范圍,這個新范圍就是我們之前記錄的最大范圍值。
代碼:
class Solution {
public:
int jump(vector<int>& nums) {
int cover = 0, cnt = 0, next = 0;
if(nums.size() == 1) return cnt;
for(int i = 0; i <= cover; i++) { //在覆蓋范圍內判斷
next = max(next, nums[i] + i); //next 記錄的是覆蓋范圍內的最大下一跳
if(i == cover) { //已經到達覆蓋范圍
if(cover < nums.size() - 1) { //但還未到達終點
cnt++; //跳數增加
cover = next; //跳到最大下一跳
if(cover >= nums.size() - 1) break; //到達終點結束
} else break;
}
}
return cnt;
}
};