注意:123和124是一个思路,他们和后面的两题思路不一样。123 124的思路主线是k次,所以对某天的股票,第k次买入 = 第k-1次卖出+p(这里的max操作先省略),第k次卖出=第k次买入后+p;
后两题主要是天数的关系,k与k-1天关联。
//121. 买卖股票的最佳时机public int maxProfit(int[] prices){if(prices.length==0) return 0;int res = 0;int min = prices[0];for (int p : prices) {min = Math.min(min,p);res = Math.max(res,p-min);}return res;}//122. 买卖股票的最佳时机 IIpublic int maxProfit2(int[] prices) {int res = 0;if(prices.length<2)return 0;for(int i = 1;i<prices.length;i++){res += prices[i-1]<prices[i]?prices[i]-prices[i-1]:0;}return res;}//123. 买卖股票的最佳时机 IIIpublic int maxProfit3(int[] prices) {int fbuy = -999999,fsel = 0;int sbuy = -999999,ssel = 0;for(int p:prices){fbuy = Math.max(fbuy,-p);fsel = Math.max(fsel,fbuy + p);sbuy = Math.max(sbuy,fsel-p);ssel = Math.max(ssel,sbuy+p);}return ssel;}//188. 买卖股票的最佳时机 IVpublic int maxProfit(int k, int[] prices) {if (k<1 || prices.length<2)return 0;if (k>prices.length/2) return maxProfit2(prices);//k足够大int[][] dp = new int[k][2];//第i天最后一个操作是 0买入 1卖出 时的最大收益;for (int i = 0; i < k; i++) dp[i][0] = Integer.MIN_VALUE;for (int p : prices){dp[0][0] = Math.max(dp[0][0],-p);dp[0][1] = Math.max(dp[0][1],dp[0][0]+p);for (int i = 1;i<k;i++){dp[i][0] = Math.max(dp[i][0],dp[i-1][1]-p);dp[i][1] = Math.max(dp[i][1],dp[i][0] + p);}}return dp[k-1][1];}
//309. 最佳买卖股票时机含冷冻期public int maxProfit_(int[] prices) {//买卖股票系列问题if(prices == null || prices.length < 2){return 0;}int n = prices.length;int [][] dp = new int[n][3];//买入 冷冻 卖出,第i天最后一个操作是xx时的最大收益;dp[0][0] = -prices[0];dp[0][1] = 0;dp[0][2] = 0;for(int i = 1;i<n;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][2]);//最后是冷冻 包含昨天就冷冻和昨天卖出今天冷冻dp[i][2] = dp[i-1][0]+prices[i];//最后是卖出 (不包含昨天就卖出) 昨天买入 今天卖出}return Math.max(dp[n-1][1],dp[n-1][2]);}
//714. 买卖股票的最佳时机含手续费//dp 设置两个数组通用解法 二维数组也可public int maxProfit(int[] prices, int fee) {int n = prices.length;if(n<2)return 0;/*int[] dp1 = new int[n];//have stock in i_dayint[] dp2 = new int[n];//dont havadp1[0] = -prices[0];dp2[0] = 0;for(int i = 1;i<n;i++){dp1[i] = Math.max(dp1[i-1],dp2[i-1]-prices[i]);dp2[i] = Math.max(dp2[i-1],dp1[i-1]+prices[i]-fee);}return dp2[n-1];*/int[][] dp = new int[n][2];//0 最后操作是买入 1 最后操作是卖出dp[0][0] = -prices[0];dp[0][1] = 0;for (int i = 1; i < n; 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] - fee);}return dp[n-1][1];}