时间:2025-06-06 23:53
人气:
作者:admin
https://leetcode.cn/problems/best-time-to-buy-and-sell-stock/?envType=problem-list-v2&envId=8At1GmaZ

状态定义:
使用一个二维数组 dp[i][0] 表示在第 i 天持有股票时的最大收益。
使用 dp[i][1] 表示在第 i 天不持有股票时的最大收益。
初始条件:
在第 0 天,如果持有股票,最大收益是 -prices[0](即买入股票的花费)。
在第 0 天,如果不持有股票,最大收益是 0(即没有操作)。
状态转移:
对于每一天 i(从 1 到 length - 1),有两种选择:
持有股票:可以选择继续持有前一天的股票,或者在今天再次买入股票(此时的收益为 -prices[i]),即 dp[i][0] = Math.max(dp[i-1][0], -prices[i])。
不持有股票:可以选择继续不持有前一天的股票,或者在今天卖出股票(此时的收益为 dp[i-1][0] + prices[i]),即 dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0] + prices[i])。
最终结果:
在最后一天(第 length-1 天),我们关心的是不持有股票的最大收益,即 dp[length-1][1]。
该算法的时间复杂度为 O(n),其中 n 为股票价格数组的长度,因为只需要遍历一次数组。
该算法的空间复杂度为 O(n),主要是由 dp 数组占用的空间决定。
class Solution { public int maxProfit(int[] prices) { //dp[i][0]持有股票得到的最大收益,dp[i][1]不持股最大收益 if(prices == null || prices.length == 0) return 0; int length = prices.length; int[][] dp = new int[length][2]; dp[0][0] = -prices[0]; dp[0][1] = 0; for(int i=1; i<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[length-1][1]; } }
https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/description/

与上一题的不同是:可以在同一天买入和卖出,且可以买卖多次。
class Solution { public int maxProfit(int[] prices) { // int sum = 0; // for(int i=0; i<prices.length-1; i++){ // if(prices[i+1] > prices[i]){ //如果后一天大于当天,则卖-买 // sum += prices[i+1]-prices[i]; // } // } // return sum; if(prices == null || prices.length == 0) return 0; int length = prices.length; int[][] dp = new int[length][2]; //在第0天持有股票的最大收益 dp[0][0] = -prices[0]; //在第0天不持股的最大收益 dp[0][1] = 0; for(int i=1; i<length; i++){ dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1]-prices[i]); //dp[i-1][1]是前几天累积的收益 dp[i][1] = Math.max(dp[i-1][1], dp[i][0]+prices[i]); } return dp[length-1][1]; } }
https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-iii/description/?envType=problem-list-v2&envId=8At1GmaZ

与前面两题的区别是:股票至多买卖两次。
class Solution { public int maxProfit(int[] prices) { int length = prices.length; int[][] dp = new int[length][5]; //第0天持有股票的最大收益 dp[0][0] = 0; dp[0][1] = -prices[0]; //第一次持有 dp[0][2] = 0; //第一次不持有 dp[0][3] = -prices[0]; //第二次持有 dp[0][4] = 0; //第二次不持有 for(int i=1; i<length; i++){ dp[i][0] = dp[i-1][0]; dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0] - prices[i]); dp[i][2] = Math.max(dp[i-1][2], dp[i-1][1] + prices[i]); dp[i][3] = Math.max(dp[i-1][3], dp[i-1][2] - prices[i]); dp[i][4] = Math.max(dp[i-1][4], dp[i-1][3] + prices[i]); } return Math.max(dp[length-1][2],dp[length-1][4]); } }
class Solution { public int maxProfit(int[] prices) { // int sum = 0; // for(int i=0; i<prices.length-1; i++){ // if(prices[i+1] > prices[i]){ //如果后一天大于当天,则卖-买 // sum += prices[i+1]-prices[i]; // } // } // return sum;