一、买卖股票的最佳时机(LeetCode121)
class Solution {
public int maxProfit(int[] prices) {
int low = Integer.MAX_VALUE;
int result = 0;
for (int i = 0; i < prices.length; i++) {
low = Math.min(low, prices[i]); // 取最左最小价格
result = Math.max(result, prices[i] - low); // 直接取最大区间利润
}
return result;
}
}
DP
class Solution {
public int maxProfit(int[] prices) {
int[][] dp = new int[prices.length][2];
dp[0][1] = 0;
dp[0][0] -= prices[0];
for (int i = 1; i < prices.length; i++) {
dp[i][0] = Math.max(dp[i-1][0],-prices[i]);//第i天持有股票即dp[i][0]
dp[i][1] = Math.max(dp[i-1][1],prices[i]+dp[i-1][0]);//第i天不持有股票即dp[i][1]
}
return dp[prices.length-1][1];
}
}
二、买卖股票的最佳时机II(LeetCode122)
DP
class Solution {
//DP
public int maxProfit(int[] prices) {
// [天数][是否持有股票]
int[][] dp = new int[prices.length][2];
// base case:0不持有,1持有
dp[0][0] = 0;
dp[0][1] = -prices[0];
for (int i = 1; i < prices.length; i++) {
// dp公式
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][0];
}
}
DP优化空间
class Solution {
//DP优化空间
public int maxProfit(int[] prices) {
int[] dp = new int[2];
// 0表示持有,1表示卖出
dp[0] = -prices[0];
dp[1] = 0;
for(int i = 1; i <= prices.length; i++){
// 前一天持有; 既然不限制交易次数,那么再次买股票时,要加上之前的收益
dp[0] = Math.max(dp[0], dp[1] - prices[i-1]);
// 前一天卖出; 或当天卖出,当天卖出,得先持有
dp[1] = Math.max(dp[1], dp[0] + prices[i-1]);
}
return dp[1];
}
}