121.买卖股票的最佳时机(简单)
121.买卖股票的最佳时机(简单)
只能交易一次,老的思路:
dp[0][i] 第i天手中没有持有股票
dp[1][i] 第i天手中持有股票
class Solution {
public int maxProfit(int[] prices) {
int len=prices.length;
int[][] dp=new int[2][len];
dp[0][0]=0;
dp[1][0]=-prices[0];
for(int i=1;i<len;i++){
dp[0][i]=Math.max(dp[1][i-1]+prices[i],dp[0][i-1]);
dp[1][i]=Math.max(-prices[i],dp[1][i-1]);
}
return dp[0][len-1];
}
}
一点优化,x1表示持有,x0表示没有持有
class Solution {
public int maxProfit(int[] prices) {
int len=prices.length;
int x0=0;
int x1=-prices[0];
for(int i=1;i<len;i++){
x1=Math.max(-prices[i],x1);
x0=Math.max(x1+prices[i],x0);
}
return x0;
}
}
122.买卖股票的最佳时机 II(简单)
122.买卖股票的最佳时机 II(简单)
可以交易无限次
class Solution {
public int maxProfit(int[] prices) {
if(prices==null||prices.length==0) return 0;
int x0=0;
int x1=-prices[0];
for(int i=1;i<prices.length;i++){
x0=Math.max(x0,x1+prices[i]);
x1=Math.max(x1,x0-prices[i]);
}
return x0;
}
}
还可以用贪心算法
class Solution {
public int maxProfit(int[] prices) {
int len=prices.length;
int res=0;
for(int i=1;i<len;i++){
res+=Math.max(0,prices[i]-prices[i-1]);
}
return res;
}
}
123.买卖股票的最佳时机 III(困难)
123.买卖股票的最佳时机 III(困难)
可以买卖最多两次
变量的名字的含义:x11已经买了1次手里有1只股票
注意循环里面的顺序
逻辑上肯定是
0(还没有买卖过)—>x11(第一次买)—>x10(第一次卖)
—>x21(第二次买)—>x20(第二次卖)
也可以设计成二位数组dp[1][1]这样
class Solution {
public int maxProfit(int[] prices) {
int len=prices.length;
if(len==0||len==1) return 0;
int x11=-prices[0];
int x10=Integer.MIN_VALUE;
int x21=Integer.MIN_VALUE;
int x20=Integer.MIN_VALUE;
for(int i=1;i<len;i++){
x11=Math.max(x11,-prices[i]);
x10=Math.max(x10,x11+prices[i]);
x21=Math.max(x21,x10-prices[i]);
x20=Math.max(x20,x21+prices[i]);
}
return x20;
}
}
188.买卖股票的最佳时机 IV(困难)
188.买卖股票的最佳时机 IV(困难)
是上一个的进阶,可以买卖k次
首先需要看下k是否很大相当于允许无限次交易—->变成题目122
class Solution {
public int maxProfit(int k, int[] prices) {
int len=prices.length;
if(len==0||len==1) return 0;
if(2*k>=len){
//unlimited sale
int x0=0,x1=-prices[0];
for(int i=1;i<len;i++){
x0=Math.max(x0,x1+prices[i]);
x1=Math.max(x1,x0-prices[i]);
}
return x0;
}else{
int[][] dp=new int[k+1][2];
for(int i=1;i<=k;i++){
if(i==1) dp[1][1]=-prices[0];
else dp[i][1]=Integer.MIN_VALUE;
dp[i][0]=Integer.MIN_VALUE;
}
for(int i=1;i<len;i++){
for(int j=1;j<=k;j++){
dp[j][1]=Math.max(dp[j][1],dp[j-1][0]-prices[i]);
dp[j][0]=Math.max(dp[j][0],dp[j][1]+prices[i]);
}
}
return dp[k][0];
}
}
}
309.最佳买卖股票时机含冷冻期(中等)
309.最佳买卖股票时机含冷冻期(中等)
冷冻期相当于是隔一天才能买,所以买入的时候不能是x0-prices[i],而是”上一次x0”-prices[i],用x2来记录上一次x0
class Solution {
public int maxProfit(int[] prices) {
int len=prices.length;
int x0=0,x1=-prices[0],x2=0;
for(int i=1;i<len;i++){
x1=Math.max(x1,x2-prices[i]);
x2=x0;
x0=Math.max(x0,x1+prices[i]);
}
return x0;
}
}
714.买卖股票的最佳时机含手续费(中等)
class Solution {
public int maxProfit(int[] prices, int fee) {
int len=prices.length;
int x0=0,x1=-prices[0];
for(int i=1;i<len;i++){
x1=Math.max(x1,x0-prices[i]);
x0=Math.max(x0,x1+prices[i]-fee);
}
return x0;
}
}