今日题目:
122. 买卖股票的最佳时机 II
55. 跳跃游戏
45. 跳跃游戏 II
今日总结
贪心的第二天。没啥套路,主要是要想到是否有局部最优导致总体最优的情况。第一道题将利润拆解的思想要记住。后面两道题要用范围去思考,单纯去模拟的话很容易把自己绕晕。
122. 买卖股票的最佳时机 II
要点
- 知道将利润拆解的话就很简单了。比如第四天到第一天的获利L4-L1可以拆为(L4-L3)+(L3-L2)+(L2-L1)
- 基于1,我们只需要考虑正的收益就行了。
代码:
func maxProfit(prices []int) int {
res := 0
for i:=1; i< len(prices); i++{
res += max(0, prices[i]-prices[i-1])
}
return res
}
func max(a int, b int) int{
if a > b{
return a
}
return b
}
55. 跳跃游戏
要点:
- 为啥 编号45是条约游戏 II ???
- 用范围去思考,贪心的变量是每一步能跳跃到的最大范围。
- 这题我自己使用递归也能做,但是会超时。
// func canJump(nums []int) bool {
// if len(nums) == 1 {
// return true
// }
// currDistance := 1
// for i := len(nums)-2; i >= 0; i-- { // 从倒数第二个元素开始
// if nums[i] >= currDistance { // 检查是否可以从当前位置跳到后面的位置
// if canJump(nums[:i+1]) { // 递归调用
// return true
// }
// }
// currDistance++
// }
// return false
// }
func canJump(nums []int) bool {
maxReach := 0 //最大能够到达的下标
for i := 0; i < len(nums); i++{
if i > maxReach {
return false
}
maxReach = max(maxReach, i+nums[i])
if maxReach >= len(nums)-1 {
return true
}
}
return false
}
func max(a int, b int) int{
if a > b {
return a
}
return b
}
45. 跳跃游戏 II
要点:
- 比前一题费点劲,但是思想是一致的。当单次跳跃范围尽可能大时总跳跃次数会尽量小。
- 这题不要考虑终点。如果当前跳跃范围的边界是终点时会额外多算一次跳跃导致答案错误。
func jump(nums []int) int {
currReach := 0
nextReach := 0
res := 0
for i:=0; i <len(nums)-1;i++{ //这里是len-1 否则会额外计算
nextReach = max(nextReach, nums[i]+i)
if i == currReach {
currReach = nextReach
res++
}
}
return res
}
func max(a int, b int) int {
if a > b{
return a
}
return b
}