[LeetCode No.122] 买卖股票最佳的时机II

题目

题解

这道题有两种思路,一种是动态规划,一种是贪心算法

解法一 动态规划

对于本题可采取动态规划的思路,首先对于每天的个人,股市收盘后只有两种股票持有状态,有或无。那么今天结束前(股市收盘前)的状态有且仅与昨天的股票状态有关
例如:
今天持有股票:
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;
    }
}
posted @ 2020-11-12 08:44  饼先生  阅读(69)  评论(0编辑  收藏  举报