代码随想录算法训练营|day32

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]
}

代码随想录文章详解

122.买卖股票的最佳时机II
55.跳跃游戏
45.跳跃游戏II

  • 18
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值