LeetCode:121. 买卖股票的最佳时机 - 力扣(LeetCode)
1.思路
买卖一次得出最大利润。暴力超时。贪心:遍历获取当前最小值,将当前值与最小值的差和当前结果值比较,获取两者之间的较大值。动态规划:每天股票价格的状态为(买入)持有或卖出,两种状态中一定是卖出的价值最大。遍历动态获取每日股票买入卖出时两者的较大值。两种状态,持有状态:前一天就持有/当天买入持有。卖出状态:前一天持有且当天卖出/前一天卖出。
2.代码实现
// class Solution {
// public int maxProfit(int[] prices) {
// int result = 0;
// for (int i = 0; i < prices.length; i++) {
// for (int j = i + 1; j < prices.length; j++) {
// result = Math.max(result, prices[j] - prices[i]);
// }
// }
// return result;
// }
// }
// class Solution {
// public int maxProfit(int[] prices) {
// // 前面某一天最小值时买入,后面某一天最大值时卖出
// int min = Integer.MAX_VALUE;
// int result = 0;
// for (int i = 0; i < prices.length; i++) {
// min = Math.min(min, prices[i]);
// result = Math.max(result, prices[i] - min);
// }
// return result;
// }
// }
class Solution {
public int maxProfit(int[] prices) {
// dp[i] 表示第 i 天卖出所获取的最大利润
// 两种状态,买入/持有,卖出
int[][] dp = new int[prices.length][2];
// 最大值一定是当天卖出
int result = 0;
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], -prices[i]);
dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] + prices[i]); // 前一天卖出状态 或者 前一天持有且当天卖出
}
return dp[prices.length - 1][1];
}
}
3.复杂度分析
时间复杂度:O(n).
空间复杂度:O(n).
LeetCode:122. 买卖股票的最佳时机 II - 力扣(LeetCode)
1.思路
可以交易多次,股票每天的状态有两种,一个是买入持有,一个是卖出,两者中卖出一定会获得最大利润,循环进行推导即可。其中,持有状态:当天买入/前天不持有且买入。卖出状态:前天持有且当天卖出/前天卖出
2.代码实现
class Solution {
public int maxProfit(int[] prices) {
// 可以交易多次
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][1], dp[i - 1][0] + prices[i]);
}
return dp[prices.length - 1][1];
}
}
3.复杂度分析
时间复杂度:O(n).
空间复杂度:O(n).