122. 买卖股票的最佳时机 II
解题思路:
假如第 0 天买入,第 3 天卖出,那么利润为:prices[3] - prices[0]。
相当于(prices[3] - prices[2]) + (prices[2] - prices[1]) + (prices[1] - prices[0])。
此时就是把利润分解为每天为单位的维度,而不是从 0 天到第 3 天整体去考虑。
那么根据 prices 可以得到每天的利润序列:(prices[i] - prices[i - 1]).....(prices[1] - prices[0])。
局部最优:收集每天的正利润,全局最优:求得最大利润。
var maxProfit = function (prices) {
let result = 0;
for (let i = 1; i < prices.length; i++) {
result += Math.max(prices[i] - prices[i - 1], 0);
}
return result;
};
55. 跳跃游戏
解题思路:
关键在于可跳的覆盖范围,不一定非要明确一次究竟跳几步,每次取最大的跳跃步数,这个就是可以跳跃的覆盖范围。
贪心算法局部最优解:每次取最大跳跃步数(取最大覆盖范围),整体最优解:最后得到整体最大覆盖范围,看是否能到终点。
var canJump = function (nums) {
let cover = 0;
for (let i = 0; i <= cover; i++) {
cover = Math.max(cover, i + nums[i]);
if (cover >= nums.length - 1) {
return true;
}
}
return false;
};
45. 跳跃游戏 II
解题思路:
移动下标达到了当前覆盖的最远距离下标时,步数就要加一,来增加覆盖距离。最后的步数就是最少步数。
这里还是有个特殊情况需要考虑,当移动下标达到了当前覆盖的最远距离下标时
- 如果当前覆盖最远距离下标不是是集合终点,步数就加一,还需要继续走。
- 如果当前覆盖最远距离下标就是是集合终点,步数不用加一,因为不能再往后走了。
var jump = function (nums) {
if (nums.length === 1) {
return 0;
}
let res = 0;
let cur = 0;
let next = 0;
for (let i = 0; i < nums.length; i++) {
next = Math.max(next, i + nums[i]);
if (cur === i) {
cur = next;
res++;
if (cur === nums.length - 1) {
break;
}
}
}
return res;
};