1 买卖股票的最佳时机 I (只买卖一次)
问题描述
给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。
你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。
返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。
思路:
1 暴力解法:循环遍历两次,记录买入和卖出的差值,取最大值
2 贪心算法;只遍历一次,记录波谷,当到达波峰时,记录差值,最后保留最大值。
3 动态规划:
(1):确定dp
dp[i][0]: 第i天持有股票,此时手里的最大金钱
dp[i][1]: 第i天不持有股票,此时手里的最大金钱
(2):状态变化规则
dp[i][0] = max(dp[i-1][0],-price[i]) // 其实这里要保证买入时股票价格尽可能小,而加了负号,所以去最大值
dp[i][1] = max(dp[i-1][0]+price[i], dp[i-1][1])
(3)初始化
dp[0][0] = -price[0]
dp[0][0] = 0
(4) 顺序:
从前往后
(5)举例子
。。。。
go语言实现
func maxProfit(prices []int) int {
//暴力
// res := 0
// for i:=0; ires {
// res = prices[j]- prices[i]
// }
// }
// }
// return res
// 贪心
// m := prices[0]
// for i:=1; im {
// if (prices[i]-m)>res {
// res = prices[i] -m
// }
// } else {
// m = prices[i]
// }
// }
// return res
//动态规划
length := len(prices)
dp := make([][]int,length)
for i:=0;ib { return a}
return b
}
买卖股票的最佳时机II (可以买卖多次)
问题描述
给定一个数组 prices ,其中 prices[i] 表示股票第 i 天的价格。
在每一天,你可能会决定购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以购买它,然后在 同一天 出售。
返回 你能获得的 最大 利润 。
思路
和上一个的动态规划思路基本一致:
不同:
买卖一次:
-price[i] :只买卖一次,很好理解。
dp[i][0] = max(dp[i-1][0],-price[i])
卖买多次:
dp[i-1][1] - price[i] : 这个时通过上一次不持有股票的状态传递下来
dp[i][0] = max(dp[i-1][0],dp[i-1][1] - price[i])
go语言实现
func maxProfit(prices []int) int {
if len(prices) == 1{
return 0
}
length := len(prices)
dp := make([][]int,length)
for i:=0;ib { return a}
return b
}
买卖股票的最佳时机系列III (限定交易的次数)
问题描述
给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)
思路
确定dp:
不管有多少个股票,我们针对一个股票有以下几种状态:
dp[i][0] : 不操作
dp[i][1] : 第一次持有股票 ,手里最大金额
dp[i][2] : 第一次 将持有股票卖出,手里最大金额
dp[i][3] : 第二次持有股票,手里最大金额
dp[i][4] : 第二次将持有股票卖出,手里最大金额
遍历所有股票,更新上述的状态,
状态变化规则:
dp[i][0] = dp[i-1][0] //不变
//1 上一次持有股票 2 上一次不持有股票 - 当前股票的价值,比较1 2大小
dp[i][1] = max( dp[i-1][1], dp[i-1][0] -price[i] )
//1 上一次不持有股票 2 上一次持有股票 + 当前股票的价值,比较1 2大小
dp[i][2] = max( dp[i-1][2] , dp[i-1][1]+price[i] )
//和上面类似
dp[i][3] = max( dp[i-1][3] , dp[i-1][2]- price[i] )
dp[i][4] = max( dp[i-1][4] , dp[i-1][3]+price[i] )
初始化
此时只有一个股票
dp[0][0] =0
dp[0][1] = -price[0]
dp[0][2] =0
dp[0][3] = -price[0]
dp[0][4] =0
遍历的顺序:
从前往后
举例
。。。。
go语言实现
func maxProfit(prices []int) int {
dp:=make([][]int,len(prices))
for i:=0;ib{
return a
}
return b
}
买卖股票的最佳时机IV (限定交易的次数为K)
问题描述
给定一个整数数组 prices ,它的第 i 个元素 prices[i] 是一支给定的股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
思路
和上述的思路一样,只是把 2 换成了 K
归纳总结。
go语言实现
func maxProfit(k int, prices []int) int {
if len(prices)==0 || k==0 {
return 0
}
dp:=make([][]int,len(prices))
for i:=0;ib{
return a
}
return b
}
买卖股票的最佳时机含冷冻期(冷冻期)
问题描述
给定一个整数数组prices,其中第 prices[i] 表示第 i 天的股票价格 。
设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):
卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
思路:
状态:
1 持有股票
2 不持有股票,但是度过了冷冻期
3 今天卖出股票,
4 不持有股票,为冷冻期
没遍历一次股票,更新状态:
go语言实现
func maxProfit(prices []int) int {
length := len(prices)
res := make([][]int,length)
for i:=0; ib { return a}
return b
}