121. 买卖股票的最佳时机
class Solution {
public int maxProfit(int[] prices) {
int res = 0;
int premin = prices[0]; //股票最低的价格
for(int i=1;i<prices.length;i++){ //从第二天开始考虑卖股票了
res = Math.max(res,prices[i]-premin);
premin = Math.min(premin,prices[i]); //记录最底价
}
return res;
}
}
方法二:动态规划(一维数组)
这个动态规划和上面的贪心没啥去别
状态转移方程:
class Solution {
public int maxProfit(int[] prices) {
int len = prices.length;
int[] dp = new int[len]; // dp[i]表示前i天的最大利润
//初始化
int minPrice = prices[0];
for(int i=1;i<len;i++){
dp[i] = Math.max(dp[i-1],prices[i]-minPrice);
minPrice = Math.min(minPrice,prices[i]);
}
return dp[len-1];
}
}
改进:dp[0]表示持有,dp[1]表示当天卖出的最大利润
class Solution {
public int maxProfit(int[] prices) {
if (prices == null || prices.length == 0) return 0;
int length = prices.length;
int[] dp = new int[2];
dp[0] = -prices[0];
dp[1] =0;
for(int i=1;i<=length;i++){
dp[0] = Math.max(dp[0],-prices[i-1]);//持有 1.(保持原样,不买也不卖) 2.或者卖出前一天的,再买入当天的
dp[1] = Math.max(dp[1], dp[0] + prices[i-1]);// 不持有 1.保持原样 2.卖出当天的
}
return dp[1];
}
}
122.买卖股票的最佳时机II
方法一:动态规划-二维数组
本题和121的唯一区别是本题股票可以买卖多次了(注意只有一只股票,所以再次购买前要出售掉之前的股票)hold[ ] 和 sold [ ] 可以用dp[ ][0] 和dp[ ][1]表示
class Solution {
public int maxProfit(int[] prices) {
int length = prices.length;
int[] hold = new int[ length+1 ]; //hold[i]表示第i天持有股票最大的收益
int[] sold = new int[ length+1];//是old[i]表示第i天卖出股票最大的收益
hold[0] = Integer.MIN_VALUE; //初始化:sold[0]=0,因为最开始不持有
for(int i=1;i<=length;i++){
int p = prices[i-1];
hold[i] = Math.max(hold[i-1],sold[i-1]-p); //卖出去再买一张新的 or 一直持有之前的
sold[i] = Math.max(sold[i-1],hold[i-1]+p); //今天卖出之前的股票 or 一直不买入
}
return sold[length];
}
}
方法二:动态规划 – 一维数组
当天的卖与不买的收益只与前一天有关
class Solution {
public int maxProfit(int[] prices) {
int length = prices.length;
//0表示持有,1表示不持有
int[] dp = new int[2];
dp[0] = -prices[0];
dp[1] =0;
for(int i=1;i<=length;i++){
dp[0] = Math.max(dp[0],dp[1]-prices[i-1]);
dp[1] = Math.max(dp[1],dp[0]+prices[i-1]);
}
return dp[1];
}
}
方法三:贪心
lass Solution {
public int maxProfit(int[] prices) {
int length = prices.length;
int res =0;
for(int i=1;i<length;i++){
res += Math.max(prices[i]-prices[i-1],0);
}
return res;
}
}
和121相比,这道题是可以多次购买,代码区别
122:既然不限制交易次数,那么再次买股票时,要加上之前的收益
//121. 只能买一次
dp[0] = Math.max(dp[0],-prices[i-1]);//持有 1.(保持原样,不买也不卖) 2.买入当天的
dp[1] = Math.max(dp[1], dp[0] + prices[i-1]);// 不持有 1.保持原样 2.卖出当天的
// 122.可以反复购买
//既然不限制交易次数,那么再次买股票时,要加上之前的收益
dp[0] = Math.max(dp[0],dp[1]-prices[i-1]);
dp[1] = Math.max(dp[1],dp[0]+prices[i-1]);