买卖股票交易(只交易一次)
思路:遍历数组找到当前交易额和目前最小交易额差价的最大一次交易
class Solution {public int maxProfit(int[] prices) {int maxP = 0;if(prices.length==0) return 0;int min =prices[0];for(int i=1;i<prices.length;i++){if(prices[i]<min) {min = prices[i];}else{maxP = Math.max(prices[i]-min,maxP);}}return maxP;}}
买卖股票(交易多次)
总的交易额 = 多次上升交易额差价之和
class Solution {public int maxProfit(int[] prices) {if(prices.length<=1) return 0;int maxP=0;int curPrice = prices[0];for(int i=1;i<prices.length;i++){if(curPrice<prices[i]){maxP += (prices[i]-curPrice);}curPrice = prices[i];}return maxP;}}
买卖股票(交易两次)
采用动态规划
分析如下:
初始状态 ——>保持不动——> 初始状态
初始状态 ——>第一次买人 ——> 买入1状态
买入1状态 ——> 保持不动
买入1状态——> 卖出 ——> 卖出1状态
卖出1状态 ——> 买入 ——> 买入2状态
卖出1状态 ——> 保持不动
卖出1状态 ——> 买入 ——> 买入2状态
买入2状态 ——> 保持不动
买入2状态 ——> 卖出 ——> 交易完成
dp[i][0][0] 原始状态 压缩状态 dp[i][0] 继续压缩状态 dp0
dp[i][1][1] 第一次买入 dp[i][1] dp1
dp[i][1][0] 第一次卖出 dp[i][2] dp2
dp[i][2][1] 第二次买入 dp[i][3] dp3
dp[i][2][0] 第二次卖出 dp[i][4] dp4
class Solution {//未状态压缩// public int maxProfit(int[] prices) {// int n = prices.length;// int dp[][][] = new int [n][3][2];// dp[0][0][0] = 0;// dp[0][1][1] = -prices[0];// dp[0][1][0] =0;// dp[0][2][1] =-prices[0];// dp[0][2][0]=0;// for(int i=1;i<n;i++){// 初始状态保持不动// dp[i][0][0] = dp[i-1][0][0];// 第一次买入// dp[i][1][1] = Math.max(dp[i-1][1][1],dp[i][0][0]-prices[i]);// 第一次卖出// dp[i][1][0] = Math.max(dp[i-1][1][0],dp[i][1][1]+prices[i]);// 第二次买入// dp[i][2][1] = Math.max(dp[i-1][2][1],dp[i][1][0]-prices[i]);// 第二次卖出// dp[i][2][0] = Math.max(dp[i-1][2][0],dp[i][2][1]+prices[i]);// }// int a = Math.max(dp[n-1][0][0],dp[n-1][1][1]);// int b = Math.max(dp[n-1][1][0],dp[n-1][2][1]);// return Math.max(dp[n-1][2][0],Math.max(a,b));// }//状态压缩1// public int maxProfit(int[] prices) {// int n = prices.length;// int dp [][] = new int [n][5];// 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<n;i++){// dp[i][0] = dp[i-1][0];// dp[i][1] = Math.max(dp[i-1][1],dp[i][0]-prices[i]);// dp[i][2] = Math.max(dp[i-1][2],dp[i][1]+prices[i]);// dp[i][3] = Math.max(dp[i-1][3],dp[i][2]-prices[i]);// dp[i][4] = Math.max(dp[i-1][4],dp[i][3]+prices[i]);// }// int a = Math.max(dp[n-1][0],dp[n-1][1]);// int b = Math.max(dp[n-1][2],dp[n-1][3]);// return Math.max(Math.max(a,b),dp[n-1][4]);// }//状态压缩2// public int maxProfit(int[] prices) {// int dp0= 0;// int dp1= -prices[0];// int dp2 =0;// int dp3=-prices[0];// int dp4 =0;// for(int i=0;i<prices.length;i++){// dp1 = Math.max(dp1,dp0-prices[i]);// dp2 = Math.max(dp2,dp1+prices[i]);// dp3 = Math.max(dp3,dp2-prices[i]);// dp4 = Math.max(dp4,dp3+prices[i]);// }// int a = Math.max(dp0,dp1);// int b = Math.max(dp2,dp3);// return Math.max(Math.max(a,b),dp4);// }采用递归来处理(深度搜索去递归状态树)public int maxProfit(int[] prices) {return dfs(prices,0,0,0);}index 表示当前交易的日期,status表示当前是买入或者卖出 表示交易的次数private int dfs(int[]prices,int index,int status,int k){//递归结束条件if(index==prices.length || k==2){return 0;}//a表示保持不动,b表示卖出,c表示买入int a=0,b=0,c=0;a= dfs(prices,index+1,status,k);if(status==1){b = dfs(prices,index,0,k+1)+prices[index];}else{c= dfs(prices,index,1,k)-prices[index];}return Math.max(Math.max(a,b),c);}}
买卖股票(交易多次)
思路:如果此时k>=n/2,n为数组长度,则就可以转化为多次交易,否则采用动态规划求解
