题目
题解
这道题有两种思路,一种是动态规划,一种是贪心算法
解法一 动态规划
对于本题可采取动态规划的思路,首先对于每天的个人,股市收盘后只有两种股票持有状态,有或无。那么今天结束前(股市收盘前)的状态有且仅与昨天的股票状态有关
例如:
今天持有股票:
1° 昨天持有股票,且没卖。 那么今天的股票利润dp1=old_dp1(昨天利润与今天利润相同)
2° 昨天未持有股票,今天购买了。 那么今天的股票利润为dp1=old_dp0-today_price
那么对于今天持有股票的最大利润,则是在1°、2°的利润取最大值。
今天未持有股票:
1° 昨天持有股票,今天卖了。 那么今天股票利润dp0=old_dp1+today_price
2° 昨天未持有股票,且今天未买。 那么今天股票利润dp0=old_dp0
到最后一天,显然未持有股票比持有股票能获得的总利润大
代码一:
import java.math.*;
class Solution {
public int maxProfit(int[] prices) {
int meta[][]=new int[2][prices.length]; //建立利润数组
meta[0][0]=0; //第一天若未持有股票,则利润为0
meta[1][0]=-prices[0]; //第一天若买进股票,则利润为-prices[0]
for(int i=1;i<prices.length;i++){
meta[0][i]=Math.max(meta[0][i-1],meta[1][i-1]+prices[i]);
meta[1][i]=Math.max(meta[1][i-1],meta[0][i-1]-prices[i]);
}
return meta[0][prices.length-1];
}
}
上面代码写好了可以发现,每天利润只与前一天的利润有关。若开辟一个利润数组来存储所以天数利润,则造成了空间浪费。
可以利用这点对代码进行改进
代码二:
import java.math.*;
class Solution {
public int maxProfit(int[] prices) {
int length=prices.length;
int dp0=0;
int dp1=-prices[0];
for(int i=1;i<length;i++){
int newdp0=Math.max(dp0, dp1+prices[i]);
int newdp1=Math.max(dp0-prices[i],dp1);
dp0=newdp0;
dp1=newdp1;
}
return dp0;
}
}
解法二:贪心算法:
股票的买卖策略
1.单独交易日:设今天的价格p1,明天p2,则今天买入,明天卖出可赚p2-p1
2.连续上涨日:设上涨股票价格为p1,p2,p3,p4,...pn,则第一天买最后一天卖收益最大即pn-p1,等价于每天买卖,即pn-p1 = (p2-p1)+(p3-p2)+...+(pn-pn-1)。
所以贪心算法就是只要今天股价比昨天高,交易。
代码三:
class Solution {
public int maxProfit(int[] prices) {
int ans = 0;
for(int i=0;i<prices.length-1;i++){
if(prices[i]<prices[i+1])
ans+=prices[i+1]-prices[i];
}
return ans;
}
}