题目:
给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。
注意: 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
1.暴力法:
class Solution {
public int maxProfit(int[] prices) {
int maxpro=0;
int min=Integer.MAX_VALUE;
for(int i=0;i<=prices.length-1;i++){
if(prices[i]<min) min=prices[i];
else if(prices[i]-min>maxpro) {
maxpro=prices[i]-min;
}
}
for(int i=2;i<prices.length;i++){
int maxpro1=0;
int min1=Integer.MAX_VALUE;
for(int j=0;j<i;j++){
if(prices[j]<min1) min1=prices[j];
else if(prices[j]-min1>maxpro1) {
maxpro1=prices[j]-min1;
}
}
int maxpro2=0;
int min2=Integer.MAX_VALUE;
for(int k=i;k<=prices.length-1;k++){
if(prices[k]<min2) min2=prices[k];
else if(prices[k]-min2>maxpro2) {
maxpro2=prices[k]-min2;
}
}
if(maxpro1+maxpro2>maxpro){
maxpro=maxpro1+maxpro2;
}
}
return maxpro;
}
}
结果惨不忍睹:执行用时:1377 ms 内存消耗:42.5 MB
经过翻阅其他人的题解,学会了动态规划的方法
1.建立dp表,(因为在这道题目中其本质是利润在每天的变化,故用利润Pro表示,列表示时间轴,行表示状态)
2.找到状态,我用了5个状态,分别是不买不卖,第一次买,第一次卖,第二次买,第二次卖
3.设定初始值
4.找到状态转移方程:本道题状态改变即1.保持原状 2.买入、卖出
即max(保持原状,买入(收益为负)、卖出(收益为正))
5利用初值和方程,可以将dp表补全全部信息
6返回表最后一行的第一列、第三列、第三列的最大值
class Solution {
public int maxProfit(int[] prices) {
int len = prices.length;
if (len < 2) {
return 0;
}
int [][] pro=new int[len][5];
pro[0][0]=0;
pro[0][1]=-prices[0];//初始化
for(int i=0;i<len;i++){
pro[i][3] = Integer.MIN_VALUE;
}//只有第一组交易完成后才能开始第二组交易
for(int j=1;j<len;j++){
pro[j][0]=0;//什么都不做
pro[j][1]=Math.max(pro[j-1][1],pro[j-1][0]-prices[j]);
pro[j][2]=Math.max(pro[j-1][2],pro[j-1][1]+prices[j]);
pro[j][3]=Math.max(pro[j-1][3],pro[j-1][2]-prices[j]);
pro[j][4]=Math.max(pro[j-1][4],pro[j-1][3]+prices[j]);
}
return Math.max(0, Math.max(pro[len - 1][2], pro[len - 1][4]));
}
}
结果:执行用时 :2 ms, 在所有 Java 提交中击败了86.35%的用户
内存消耗 :42.4 MB, 在所有 Java 提交中击败了16.95%的用户