Leetcode——股票类型题目总结

一,前言

总结的题目如下:

121,Best Time to Buy and Sell Stock

122,Best Time to Buy and Sell Stock 2

123,Best Time to Buy and Sell Stock 3

188,Best Time to Buy and Sell Stock 4

309,Best Time to Buy and Sell Stock with Cooldown

714,Best Time to Buy and Sell Stock with Transaction Fee

二,Best Time to Buy and Sell Stock

1,分析

题意是说股票只能卖一次,怎么获得最大的利润。

这道题应该是最简单的数组题目,时间复杂度O(N)

2,步骤

①第一次遍历数组获取每个值当前最小值

②第二次遍历数组,用当前值减去当前可能最小值,求出其中的最小值

3,代码

func maxProfit1(prices []int) int {
	length := len(prices)
	if length < 2 {
		return 0
	}
	var max int
	min := prices[0]
	minArray := make([]int, length)
	for i, price := range prices {
		if price < min {
			min = price
		}
		minArray[i] = min
	}

	for i, price := range prices {
		tmpMax := price - minArray[i]
		if tmpMax > max {
			max = tmpMax
		}
	}
	return max
}

三,Best Time to Buy and Sell Stock 2

1,分析

题意是可以卖任意多次,怎么获得最大的利润

这道题也是一道简单的字符串问题,时间复杂度O(N)

2,步骤

① 后数只要比前数大,那么就增加他们的差值

3,代码

func maxProfit2(prices []int) int {
	maxProfit := 0
	for i := 1; i < len(prices); i++ {
		if prices[i] > prices[i-1] {
			maxProfit += prices[i] - prices[i-1]
		}
	}
	return maxProfit
}

四,Best Time to Buy and Sell Stock 3

1,分析,题意是可以卖两次,怎么获得最大的利润

这道题是一道动态规划题,时间复杂度O(2N)

2,步骤

① 用两个值来表示当前最佳和全局最佳,i表示天,j表示次数

local[i][j] = max(global[i-1][j] + diff>0?diff:0, local[i-1][j] + diff)
global[i][j] = max(local[i][j] + global[i-1][j])

3,代码

func maxProfit3(prices []int) int {
	length := len(prices)
	if length < 2 {
		return 0
	}
	i := 1
	local := make([]int, 3)
	global := make([]int, 3)

	for i < length {
		diff := prices[i] - prices[i-1]
		for j := 2; j >= 1; j-- {
			//全局最佳,可以少加一次,当前最佳必须换算到当前节点
			if diff > 0 {
				local[j] = int(math.Max(float64(global[j-1]+diff), float64(local[j]+diff)))
			} else {
				local[j] = int(math.Max(float64(global[j-1]), float64(local[j]+diff)))
			}
			global[j] = int(math.Max(float64(global[j]), float64(local[j])))
		}
		i++
	}
	return global[2]
}

五,Best Time to Buy and Sell Stock 4

 

1,分析

题意是可以卖k次,怎么获得最大的利润

这道题是一道动态规划题,时间复杂度O(kN)

2,步骤

① 和上题类似,用两个值来表示当前最佳和全局最佳,i表示天(从上题的2天变成了k天),j表示次数

local[i][j] = max(global[i-1][j] + diff>0?diff:0, local[i-1][j] + diff)

global[i][j] = max(local[i][j] + global[i-1][j])

② 在这里我们要注意k大于length的问题,这周情况和题二一样

3,代码

func maxProfit4(k int, prices []int) int {
	length := len(prices)
	if length < 2 {
		return 0
	}
	if k > length {
		return sum(prices)
	}
	i := 1
	local := make([]int, k+1)
	global := make([]int, k+1)

	for i < length {
		diff := prices[i] - prices[i-1]
		for j := k; j >= 1; j-- {
			//全局最佳,可以少加一次,当前最佳必须换算到当前节点
			if diff > 0 {
				local[j] = int(math.Max(float64(global[j-1]+diff), float64(local[j]+diff)))
			} else {
				local[j] = int(math.Max(float64(global[j-1]), float64(local[j]+diff)))
			}
			global[j] = int(math.Max(float64(global[j]), float64(local[j])))
		}
		i++
	}
	return global[k]
}

func sum(prices []int) int {
	var sum int
	for i := 1; i < len(prices); i++ {
		diff := prices[i] - prices[i-1]
		if diff > 0 {
			sum += diff
		}
	}
	return sum
}

六,Best Time to Buy and Sell Stock with Cooldown

1,分析

题目意思是可以交易多次,但每次卖出后最少要休息一天

动态规划题,时间复杂度O(N)

2,步骤

① 网上说维护三个数组,分别是bug,rest,sel数组

buy[i] = max(sel[i-2] - price, buy[i-1])
sel[i] = max(buy[i-1] + price, sel[i-1])② 其实我们在这里不用关心rest数组的,bug数组一定是在sel数组后两天以上

3,代码

func maxProfit(prices []int) int {
	length := len(prices)
	if length < 2 {
		return 0
	}
	buys := make([]int, length)
	sels := make([]int, length)

	for i, price := range prices {
		if i == 0 {
			buys[i] = -price
		} else if i == 1 {
			sels[i] = int(math.Max(float64(buys[i-1]+price), float64(sels[i-1])))
			buys[i] = int(math.Max(float64(-price), float64(buys[i-1])))
		} else {
			buys[i] = int(math.Max(float64(sels[i-2]-price), float64(buys[i-1])))
			sels[i] = int(math.Max(float64(buys[i-1]+price), float64(sels[i-1])))
		}
	}
	return sels[length-1]
}

 

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值