题目链接:122. 买卖股票的最佳时机 II
题目描述
给你一个整数数组 prices
,其中 prices[i]
表示某支股票第 i
天的价格。
在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。
返回 你能获得的 最大 利润 。
示例 1:
输入:prices = [7,1,5,3,6,4] 输出:7 解释:在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。 随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6 - 3 = 3 。 总利润为 4 + 3 = 7 。
示例 2:
输入:prices = [1,2,3,4,5] 输出:4 解释:在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。 总利润为 4 。
示例 3:
输入:prices = [7,6,4,3,1] 输出:0 解释:在这种情况下, 交易无法获得正利润,所以不参与交易可以获得最大利润,最大利润为 0 。
提示:
1 <= prices.length <= 3 * 104
0 <= prices[i] <= 104
文章讲解:代码随想录
视频讲解:贪心算法也能解决股票问题!LeetCode:122.买卖股票最佳时机II_哔哩哔哩_bilibili
题解1:暴力法
思路:将价格数组看成一个函数图像,寻找极大值点和极小值点,极小值点就是买入的点,极大值点就是卖出的点,结合起来就是总利润,最左和最右的值要特殊处理。
/**
* @param {number[]} prices
* @return {number}
*/
var maxProfit = function(prices) {
let res = 0;
let pre = 0;
let min = prices[0];
for (let i = 0; i < prices.length - 1; i++) {
let cur = prices[i + 1] - prices[i];
// 判断极大值
if (pre >= 0 && cur < 0) {
res += prices[i] - min; // 将利润累加
min = prices[i + 1];
pre = cur;
}
// 判断极小值
if (pre <= 0 && cur > 0) {
if (prices[i] < min) {
min = prices[i];
}
pre = cur;
}
}
// 最右边的元素特殊处理
if (prices.length > 1 && pre >= 0 && prices[prices.length - 1] >= prices[prices.length - 2]) {
res += prices[prices.length - 1] - min;
}
return res;
};
分析:时间复杂度为 O(n),空间复杂度为 O(1)。
题解2:贪心算法
思路:可以模拟每天卖出之前的股票并买入新的股票,每个阶段都取正数的利润,最后得到的总利润就是最大的。
/**
* @param {number[]} prices
* @return {number}
*/
var maxProfit = function(prices) {
let res = 0;
for (let i = 1; i < prices.length; i++) {
if (prices[i] > prices[i - 1]) {
res += prices[i] - prices[i - 1];
}
}
return res;
};
分析:时间复杂度为 O(n),空间复杂度为 O(1)。
收获
贪心算法没有固定的方法,对于每道题目的思路都不一样。如果模拟出可以使用贪心算法将局部最优合成全局最优。