本文将使用动态规划的方法来解决两个买卖股票的问题:121. 买卖股票的最佳时机和122.买卖股票的最佳时机II。这两个问题都是经典的股票买卖问题,其中121是一次买卖,122是多次买卖。本文将分别介绍两个问题的动态规划解法,并给出Java代码实现。
-
- 买卖股票的最佳时机
这个问题的描述如下:给定一个数组prices,其中prices[i]是第i天股票的价格。你只能在第i天买入,第j天卖出(i<j)一次。问最大的收益是多少?
我们可以使用动态规划的思想来解决这个问题。在第i天卖出时,我们需要在前i-1天中找到一个最小的买入价格。因此,我们可以定义状态f(i)为第i天卖出所能获得的最大收益。那么,f(i)的值可以通过以下递推式计算:
f(i) = max(f(i-1), prices[i] - min_price)
其中,min_price是前i-1天中的最小价格。我们可以用一个变量min_price来保存前i-1天中的最小价格,以便计算f(i)。
Java代码如下:
public int maxProfit(int[] prices) {
if (prices == null || prices.length == 0) {
return 0;
}
int minPrice = prices[0];
int maxProfit = 0;
for (int i = 1; i < prices.length; i++) {
maxProfit = Math.max(maxProfit, prices[i] - minPrice);
minPrice = Math.min(minPrice, prices[i]);
}
return maxProfit;
}
时间复杂度为O(n),空间复杂度为O(1)。
- 122.买卖股票的最佳时机II
这个问题的描述如下:给定一个数组prices,其中prices[i]是第i天股票的价格。你可以进行多次买卖(但不能同时买入多个股票),问最大的收益是多少?
同样,我们可以使用动态规划的思想来解决这个问题。我们可以定义状态f(i)为第i天结束后,手中拥有股票所能获得的最大收益。我们可以用变量buy来表示当前持有股票的状态,如果当前持有股票,那么f(i)的值就是f(i-1),否则f(i)的值就是f(i-1)+prices[i]-prices[i-1](也就是在前一天买入,今天卖出)。最后,我们只需要返回f(n-1)即可,其中n是prices数组的长度。
Java代码如下:
public int maxProfit(int[] prices) {
if (prices == null || prices.length == 0) {
return 0;
}
int buy = -prices[0];
int sell = 0;
for (int i = 1; i < prices.length; i++) {
int tmp = buy;
buy = Math.max(buy, sell - prices[i]);
sell = Math.max(sell, tmp + prices[i]);
}
return sell;
}
时间复杂度为O(n),空间复杂度为O(1)。
总结
本文介绍了使用动态规划的方法来解决买卖股票的最佳时机问题。对于121问题,我们可以用一个变量来保存前i-1天中的最小价格,并逐步计算出第i天卖出所能获得的最大收益。对于122问题,我们可以用两个变量来分别保存当前持有股票和当前不持有股票时的最大收益,并逐步计算出f(n-1)。这两个问题都是经典的股票买卖问题,值得深入研究。