算法day35-动态规划(8)
目录
- 买卖股票的最佳时机
- 买卖股票的最佳时机II
- 买卖股票的最佳时机III
一、买卖股票的最佳时机
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]; } }
二、买卖股票的最佳时机II——买卖多次
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]; } }
三、买卖股票的最佳时机III
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]); } }
浙公网安备 33010602011771号