买卖股票交易(只交易一次)
思路:遍历数组找到当前交易额和目前最小交易额差价的最大一次交易
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为数组长度,则就可以转化为多次交易,否则采用动态规划求解