总结的题目如下:
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
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
}
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
}
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]
}
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
}
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]
}