714.买卖股票的最佳时机含手续费

76 阅读1分钟

题目:
给定一个整数数组 prices,其中 prices[i]表示第 i 天的股票价格 ;整数 fee 代表了交易股票的手续费用。

你可以无限次地完成交易,但是你每笔交易都需要付手续费。如果你已经购买了一个股票,在卖出它之前你就不能再继续购买股票了。

返回获得利润的最大值。

注意: 这里的一笔交易指买入持有并卖出股票的整个过程,每笔交易你只需要为支付一次手续费。
算法:
方法一:贪心

func maxProfit(prices []int, fee int) int {
	profit := 0
	// 买入成本为股价+手续费
	buy := prices[0] + fee
	for i := 0; i < len(prices); i ++ {
		// 假装卖出股票, 买入成本更新为prices[i],
		// 如果后面还有比prices[i]更高的股价,则继续卖出获益
		if buy < prices[i] {
			profit = profit + prices[i] - buy
			buy = prices[i]
		// prices[i]买入成本更低,反悔了,更改买入成本
		} else if  prices[i] + fee < buy  {
			buy = prices[i] + fee
		}
	}
	return profit
}

方法二:动态规划

func maxProfit(prices []int, fee int) int {
	if len(prices) < 2 {
		return 0
	}
	// 卖出计算fee
	// 第i天不持有股票的最大利润 dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i] - fee)
	// 第i天持有股票的最大利润 dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i])
	dp := make([][]int, 2)
	dp[0] = []int{0, -prices[0]}
	for i := 1; i < len(prices); i ++ {
		dp[1] = []int{max(dp[0][0], dp[0][1] + prices[i] - fee), max(dp[0][1], dp[0][0] - prices[i])}
		dp[0] = dp[1]
	}
	return dp[1][0]
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}