LeetCode 精选TOP面试题 算法题 122.买卖股票的最佳时机II -算法&测试-easy模式
给定一个数组,它的第i个元素是一支股票第i天的价格。
设计一个算法来计算你所能获得的最大利润。你可以尽可能多地完成更多的交易(多次买卖一支股票)。
你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票
示例1:[7,1,5,3,6,4]
输出:7
解释:在第二天买入(1),第三天卖出(5);在第4天买入(3),第五天卖出(6),共获得利润7。
线性规划解决
package leetcode.easy;
public class Solution122 {
public static void main(String[] args) {
int[] prices = {7,1,5,3,6,4};
S122MaxProfitII testMaxProfitII = new S122MaxProfitII();
S121MaxProfitI testMaxProfitI = new S121MaxProfitI();
System.out.println(testMaxProfitII.maxPro(prices));
System.out.println(testMaxProfitI.maxPro(prices));
}
}
//122.买卖股票的最佳时机II
class S122MaxProfitII{
public int maxPro(int[] prices) {
int len = prices.length;
if (len<2) {
return 0;
}
int[][] dp = new int[len][2];
dp[0][0]=0;
dp[0][1]=-prices[0];
for (int i = 1; i < len; i++) {
dp[i][0]=Math.max(dp[i-1][0], dp[i-1][1]+prices[i]);
dp[i][1]=Math.max(dp[i-1][0]-prices[i], dp[i-1][1]);
//注意:可以有多次买入 只要昨日不持股,今日就能买入
}
return dp[len-1][0];
}
}
//121.买卖股票的最佳时机
class S121MaxProfitI{
public int maxPro(int[] prices) {
int len = prices.length;
if (len<2) {
return 0;
}
//dp[i][j] 下标i这一天结束时 手上的持股状态为j时,持有的现金数
//i具有前缀性质,即考虑了之前天数的交易
//j=0表示当前不持股,j=1表示当前持股
int[][] dp=new int[len][2];
//第一天 下标0
dp[0][0]=0;
dp[0][1]=-prices[0];
//从第二天 下标1 开始遍历
//dp[i][0] 当天不持股:1.昨天不持股,今天什么都不做 2.昨天持股,今日卖出
//dp[i][1] 当天持股:1.昨天不持股,今天买入 2.昨天持股,今天什么都不做
for (int i = 1; i < len; i++) {
dp[i][0]=Math.max(dp[i-1][0], dp[i-1][1]+prices[i]);
dp[i][1]=Math.max(-prices[i], dp[i-1][1]);
//注意:今天的持股状态dp[i][1]只能从 没有买入前的不持股状态 或 昨天的已持股状态 而来
//保证只有一次买入
}
//最后那一天 下标len-1 肯定已将股票卖出 j=0
return dp[len-1][0];
}
}
参考:
- https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/solution/bao-li-mei-ju-dong-tai-gui-hua-chai-fen-si-xiang-b
- https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/solution/tan-xin-suan-fa-by-liweiwei1419-2