Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
前言
力扣第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 。
一、思路
这一题与前面一题力扣第121题-买卖股票的最佳时机是类似的,都是需要求得最大的利润。但是这一题中是可以多次购买并卖出的。
题目中有几个重要的点需要注意以下:
- 可以在时间段内多次购买并卖出
- 同一天内最多只能持有一只股票
我们注意对于每一天来说,只能有两种状态:要么持有一支股票,要么不持有股票,我们不妨将持有和不持有股票对应的收益存到数组中。
动态规划
我们用两个一维数组来存储这两个状态对应的收益:
dpNot[]:当前不持有股票dpHas[]:持有当天的股票
边界情况:
第一天不持有股票收益为0,故dpNot[0] = 0
第一天持有股票收益为负的,dpHas[0] = -prices[0]
状态转移方程如下所示:
第 i 天如果不持有股票,则为前一天也不持有股票或前一天持有股票但在今日卖出中的最大值。
第 i 天如果持有股票,则为前一天也持有股票或前一天不持有股票但买入今日的股票。
dpNot[i] = Math.max(dpNot[i - 1], dpHas[i - 1] + prices[i])
dpHas[i] = Math.max(dpHas[i - 1], dpNot[i - 1] - prices[i])
我们遍历所有的天,初始化所有 持有或不持有股票对应的收益,然后返回最后一天不持有的收益 dpNot[len] 即可(因为利润最大化,最后一天一定不能持有股票)。
二、实现
实现代码
实现代码与思路中保持一致
public int maxProfit(int[] prices) {
int len = prices.length;
int[] dpNot = new int[len]; // 不持有
int[] dpHas = new int[len]; // 持有
dpNot[0] = 0; // 第一天卖出收益为0
dpHas[0] = -prices[0]; // 第一天持有收益为负的
for (int i = 1; i < len; ++i) { // 从第二天开始
// 比较当前是持有和卖出的利润
dpNot[i] = Math.max(dpNot[i - 1], dpHas[i - 1] + prices[i]);
dpHas[i] = Math.max(dpHas[i - 1], dpNot[i - 1] - prices[i]);
}
return dpNot[len - 1];
}
测试代码
public static void main(String[] args) {
int[] nums = {7,1,5,3,6,4};
new Number122().maxProfit(nums);
}
结果
三、总结
感谢看到最后,非常荣幸能够帮助到你~♥
如果你觉得我写的还不错的话,不妨给我点个赞吧!如有疑问,也可评论区见~