121. 买卖股票的最佳时机
只能买卖一次股票,求最大利润
贪心算法
从左边开始找到左边的最小值(让买入价尽量便宜),然后不断求最大的利润(保留最大值,取最大区间利润)
class Solution {
public int maxProfit(int[] prices) {
int min = prices[0];
int res = 0;
for (int i = 0; i < prices.length; i++) {
min = Math.min(min, prices[i]);
res = Math.max(res, prices[i] - min);
}
return res;
}
}
动规
对于每一天分为两种状态,即持有股票和不持有股票的最多现金,可以从i-1推出。
dp[i][0] 表示第i天持有股票所得最多现金
其实一开始现金是0,那么加入第i天买入股票现金就是 -prices[i], 这是一个负数。
dp[i][1] 表示第i天不持有股票所得最多现金
持有 不代表 买入,可以是保持了持有的状态。
class Solution {
public int maxProfit(int[] prices) {
int[][] dp = new int[prices.length][2];
dp[0][0] = -prices[0];
dp[0][1] = 0;
// dp[i][0] hold
// dp[i][1] not hold
for (int i = 1; i < prices.length; i++){
dp[i][0] = Math.max(dp[i-1][0], -prices[i]);
dp[i][1] = Math.max(dp[i-1][0]+prices[i], dp[i-1][1]);
}
return Math.max(dp[prices.length-1][0], dp[prices.length-1][1]);
}
}
● 122.买卖股票的最佳时机II
和上题相似,不同在于可以多次买卖,在推导dp[i][0]的时候,第i天买入股票的情况,所持有的现金可能有之前买卖过的利润,要基于昨天的情况减去当天购买的支出。
class Solution {
public int maxProfit(int[] prices) {
// dp[i][0] max profit if hold the stock on day i
// dp[i][1] not hold the stock
int[][] dp = new int[prices.length][2];
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][0]+prices[i], dp[i-1][1]);
}
return Math.max(dp[dp.length-1][0], dp[dp.length-1][1]);
}
}