题目
给定一个数组 prices ,其中 prices[i] 表示股票第 i 天的价格。
在每一天,你可能会决定购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以购买它,然后在 同一天 出售。 返回 你能获得的 最大 利润 。
- 来源:力扣(LeetCode)
- 链接:leetcode-cn.com/problems/be…
- 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解法一
思路
- 只要卖出的价钱比买入的价钱高就可以获利。
- 如果买入的第二天又跌了,按照更低的价钱买入(持续有低价,持续按照低价买入)。
- 如果上次卖便宜了,那么可以重新卖个高价(持续有高价,则持续重新卖;如果突然掉价了,那么就要重新买入了)。
代码
public int maxProfit(int[] prices) {
int minPrice = Integer.MAX_VALUE;
int maxProfit = 0;
// 记录上一次卖出的价钱。如果为-1,表示还没有卖出过
int lastPrice = -1;
for (int i = 0; i < prices.length; i++) {
if (prices[i] < minPrice) {
// 表示买入
minPrice = prices[i];
lastPrice = -1;
} else {
if (prices[i] > lastPrice) {
// 表示卖出
maxProfit = maxProfit - (lastPrice == -1 ? 0 : (lastPrice - minPrice)) + (prices[i] - minPrice);
lastPrice = prices[i];
} else {
// 表示买入
minPrice = prices[i];
lastPrice = -1;
}
}
}
return maxProfit;
}
复杂度
时间复杂度:O(n) 空间复杂度:O(1)
解法二
思路
动态规划的方法。
代码
public int maxProfit(int[] prices) {
int n = prices.length;
// dp[i][0] // 不持有第i天股票时的最大利润
// dp[i][1] // 持有第i天股票时的最大利润
int[][] dp = new int[n][2];
dp[0][0] = 0; dp[0][1] = -prices[0];
for (int i = 1; i < n; i++) {
// 第i天不持有股票可以由2个状态迁移而来
// - 第i-1天也不持有股票
// - 第i-1天持有股票,而i天不持有股票,说明i天卖出了,可以获得利润
dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1] + prices[i]);
dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0] - prices[i]);
}
return dp[n-1][0];
}
复杂度
时间复杂度:O(n) 空间复杂度:O(n)
update20220804
class Solution {
public int maxProfit(int[] prices) {
int n = prices.length;
int buy = -prices[0];
int sell = 0;
for (int i = 1; i < n; i++) {
buy = Math.max(buy, sell - prices[i]);
sell = Math.max(sell, buy + prices[i]);
}
return sell;
}
}
解法三
思路
贪心算法
其实只要后一天比前一天的价钱高,就能获利。
注意:可以这么做是因为,可以在同一天买入也可以在同一天卖出。
代码
public int maxProfit(int[] prices) {
int res = 0;
for (int i = 1; i < prices.length; i++) {
res += Math.max(0, prices[i] - prices[i-1]);
}
return res;
}
复杂度
时间复杂度:O(n) 空间复杂度:O(1)