122.买卖股票的最佳时机II
(1)贪心
只要今天比昨天赚,就卖
func maxProfit(prices []int) int {
res := 0
if len(prices) <= 1 {
return res
}
for i := 1; i < len(prices); i++ {
if prices[i] > prices[i-1] {
res += prices[i] - prices[i-1]
}
}
return res
}
(2)动态规划
将股票卖出后才会有收益,设置初始变量buy = -price[0], sell = 0
因为每次最多只能保留一张股票,
第i天 buy情况取最大值:前一天卖第二天买,或者保留之前的状态
第i天 sell情况取最大值:前一天买第二天卖,或者保留之前的状态
func maxProfit(prices []int) int {
buy, sell := -prices[0], 0
if len(prices) <= 1 {
return sell
}
for i := 1; i < len(prices); i++ {
buy = max(buy, sell-prices[i])
sell = max(buy+prices[i], sell)
}
return sell
}
55.跳跃游戏
如果当前位置的跳跃长度能覆盖终点则成功。维护当前最远跳跃距离,i只能在最远跳跃长度内移动
(1)贪心:在可跳跃范围内,每次取最大跳跃次数
func canJump(nums []int) bool {
coverRange := 0
for i := 0; i <= coverRange; i++ {
coverRange = max(coverRange, i+nums[i])
if coverRange >= len(nums) - 1 {
return true
}
}
return false
}
(2)动态规划
dp[i]:[0,i]范围内任意位置,下一跳可以跳到的最远位置。
从i位置出发,dp[i] = nums[i] + i;不从i位置出发dp[i] = dp[i - 1]
注意:
若数组长度大于1,但是nums[0] == 0,无法继续前进;
若下一跳能跳到的最远位置为当前位置,不能往前走了。 eg:当前位置nums[i]=0
func canJump(nums []int) bool {
if len(nums) < 2 {
return true
}
if nums[0] == 0 {
return false
}
dp := make([]int, len(nums))
dp[0] = nums[0]
for i := 1; i < len(nums); i++ {
dp[i] = max(dp[i-1], i+nums[i])
if dp[i] > = len(nums)-1 {
return true
}
if dp[i] == i {
return false
}
}
return false
}
45.跳跃游戏II
(1)贪心:若当前位置是能走到的最远位置离,count++,更新下一个能走到的最远位置
func jump(nums []int) int {
count := 0
if len(nums) < 2 {
return count
}
curStep := 0
nextStep := 0
for i := 0; i < len(nums); i++ {
nextStep = max(nextStep, i+nums[i])
if curStep == i {
count++
curStep = nextStep
}
if curStep >= len(nums) - 1 {
break
}
}
return count
}
(2)动态规划
dp为到达当前位置跳跃的最小次数
当前位置为i时,下一跳的可扩展边界为j,如果下一跳位置从未到达过,dp[j]=dp[i]+1
若到达过,选取min(到当前位置j
的前一跳位置i
的最小次数 + 1,当前位置的最小跳跃次数)
func jump(nums []int) int {
if len(nums) < 2 {
return 0
}
dp := make([]int, len(nums))
for i := 0; i < len(nums); i++ {
for j := i + 1; j <= min(i+nums[i], len(nums)-1); j++ {
if dp[j] == 0 {
dp[j] = dp[i] + 1
} else {
dp[j] = min(dp[j], dp[i]+1)
}
}
}
return dp[len(nums)-1]
}