题目: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 。
- 提示:
1 <= prices.length <= 3 * 10^4
0 <= prices[i] <= 10^4
思路1
这个问题可以使用贪心算法来解决。贪心算法的思想是:只要有利润,就进行交易。这意味着每次价格上涨的那一天,我们都会进行一次交易,从而累积所有的上涨部分。
- 时间复杂度:O(n)
- 空间复杂度:O(1)
代码
public int maxProfit(int[] prices) {
int maxProfit = 0;
for (int i = 1; i < prices.length; i++) {
if (prices[i] > prices[i - 1]) {
maxProfit += prices[i] - prices[i - 1];
}
}
return maxProfit;
}
思路2
可以使用动态规划来解决这个问题。动态规划方法的核心思想是通过维护两个状态数组来跟踪买入和卖出的最大利润。在每一天,我们需要决定是否进行买入或卖出操作。
具体来说,我们定义两个数组 dp[i][0]
和 dp[i][1]
:
dp[i][0]
表示第i
天结束时持有现金的最大利润。dp[i][1]
表示第i
天结束时持有股票的最大利润。
状态转移方程
如果第
i
天持有现金,那么有两种可能:- 第
i-1
天也持有现金,则dp[i][0] = dp[i-1][0]
。 - 第
i-1
天持有股票,在第i
天卖出股票,则dp[i][0] = dp[i-1][1] + prices[i]
。
因此,dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1] + prices[i])
。
- 第
如果第
i
天持有股票,那么有两种可能:- 第
i-1
天也持有股票,则dp[i][1] = dp[i-1][1]
。 - 第
i-1
天持有现金,在第i
天买入股票,则dp[i][1] = dp[i - 1][0] - prices[i]
。
因此,
dp[i][1] = Math.max(dp[i-1][1], dp[i - 1][0] - prices[i])
。- 第
时间复杂度:O(n)
空间复杂度:O(n)
代码
public int maxProfit(int[] prices) {
int[][] dp = new int[prices.length][2];
// 开始持有现金
dp[0][0] = 0;
// 开始持有股票
dp[0][1] = -prices[0];
for (int i = 1; i < prices.length; 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[prices.length - 1][0];
}