买卖股票的最佳时机 II
题目链接:力扣题目链接
难度:中等
给定一个数组 prices ,其中 prices[i] 表示股票第 i 天的价格。
在每一天,你可能会决定购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以购买它,然后在 同一天 出售。
返回 你能获得的 最大 利润 。
示例 :
输入: prices = [7,1,5,3,6,4]
输出: 7
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。
思路
此题要点:只可以买一只股票,当前只有买股票或者卖股票的操作。想要获得利润至少要两天为一个交易单元。
第一天没有利润,至少第二天才有利润,所以利润的序列比股票序列少一天。
收集正利润的区间,就是股票买卖的区间,而我们只要关注最终利润,不需要记录区间。
局部最优:收集每天的正利润,全局最优:求出最大利润。
由于不限制交易次数,只要今天股价比昨天高,就交易.将整个区间划分为长度为1的n个区间,找到所有利润为正值的区间(上升区间)相加即可。
贪心代码
class Solution{
public int maxProfit(int[] prices) {
int result = 0;
for(int i = 1; i<prices.length;i++){
result += Math.max(prices[i] - prices[i-1],0);
}
return result;
}
}
动态规划
class Solution{
public int maxProfit(int[] prices) {
if(prices == null || prices.length == 0) return 0;
int[][] dp = new int[prices.length][2];
// 可以将每天持有与否的情况分别用 dp[i][0] 和 dp[i][1] 来进行存储
//dp[i][0] 表示持有
//dp[i][1] 表示卖出
dp[0][0] = -prices[0];
dp[0][1] = 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][1];
}
}