LeetCode 122. 买卖股票的最佳时机 II
思路:
这道题也可以用贪心的方法,因为当天是可以同时操作买入和卖出的,也就是说每天的收益可以单独计算,那么贪心的策略就很简单了:把每天的正收益加起来就可以了。计算每天的收益可以用当天的减去前一天的,只要收益为正就累计起来,即可得到最终答案。
代码:
class Solution {
public:
int maxProfit(vector<int>& prices) {
int profit = 0;
if (prices.size() < 2)
return 0;
for (int i = 1; i < prices.size(); i++)
{
if (prices[i] > prices[i-1])
profit += prices[i] - prices[i-1];
}
return profit;
}
};
LeetCode 55. 跳跃游戏
思路:
其实这道题目和贪心的关联不大,只需要维护一个当前能到达的最大值就行。当前所能到达的最远距离,也就是当前能移动的范围,遍历数组的时候动态更新这个范围,当所能达到的最大范围内包含更大的范围,就更新所能达到的范围,直到所能达到的范围包含了终点。
代码:
class Solution {
public:
bool canJump(vector<int>& nums) {
int maxJump = nums[0];
for (int i = 0; i < nums.size(); i++)
{
if (maxJump >= i)
maxJump = max(maxJump, i + nums[i]);
if (maxJump >= nums.size() - 1)
return true;
}
return false;
}
};
LeetCode 45. 跳跃游戏 II
思路:
这道题目要比上一题55. 跳跃游戏难很多,和寻找最大能到达的范围不一样,本题要找的是到达指定范围时所需要的最小步数,所以重点是如何计算这个步数。本题依然用贪心法,策略为:在当前能到达的范围内,寻找到下一个能到达的最远范围。所以我们需要curPos和nextPos两个下标,分别代表了当前范围和下一步能到达的范围,步数初始化为0,所以两个下标的初始化也为0,因为我们还一步都没开始走。
当开始遍历数组的时候,首先检查curPos是否包括了终点,如果包括的话则直接返回当前走的步数,如果没有包括终点,则根据当前位置能走的步数更新下一步的最大范围。如果当前位置已经是当前步数下所能到达的最大范围,并且最大范围不包括终点,则将步数加1,并更新当前的最大范围,即代表了我们又往前走了一步。因为如果是终点的话,就不需要步数加1了,这代表了我们走的这些步数已经足够达到终点。
代码:
class Solution {
public:
int jump(vector<int>& nums) {
int step = 0;
int curPos = 0;
int nextPos = 0;
for (int i = 0; i < nums.size(); i++)
{
if (curPos >= nums.size() - 1)
return step;
// 更新下一步覆盖范围
nextPos = max(nextPos, nums[i] + i);
// 如果已经走到了当前覆盖范围的终点
if (curPos == i)
{
// 增加步数,更新当前覆盖范围
step++;
curPos = nextPos;
}
}
return step;
}
};