● 122.买卖股票的最佳时机II
● 55. 跳跃游戏
● 45.跳跃游戏II
122.买卖股票的最佳时机II
关联 leetcode 122.买卖股票的最佳时机II
-
思路
- 局部最优:
- 只收获每天的正利润
- 全局最优
- 局部最优累计的最大利润
- 当天卖了还可以用当天的价格买入
- 局部最优:
-
题解
func maxProfit(prices []int) int { res := 0 // 从第二天开始计数, 当天加个高于前天就收获利润 for i := 1; i < len(prices); i++ { if prices[i]-prices[i-1] > 0 { res += prices[i] - prices[i-1] } } return res }
55. 跳跃游戏
关联 leetcode 55. 跳跃游戏
-
思路
- 使用覆盖范围来判断是否能跳到最后一个格子
- 累加当前能跳到的所有格子的覆盖范围,取最大值
- 使用覆盖范围来判断是否能跳到最后一个格子
-
题解
func canJump(nums []int) bool { if len(nums) < 2 { return true } cover := 0 end := len(nums) - 1 // 从起点到当前当前已覆盖的范围内, 逐步遍历, 累计覆盖范围 for i := 0; i <= cover; i++ { if i+nums[i] > cover { //当前位置能跳到的最远距离比当前覆盖范围大, 更新覆盖范围 cover = i + nums[i] } if cover >= end { //走到最后一个位置 return true } } return false }
45.跳跃游戏II
关联 leetcode 45.跳跃游戏II
- 思路
- 依然从覆盖范围思考出发
- 在覆盖范围内,以最小的步数增加覆盖范围,当覆盖范围包含了终点就是最小步数
- 统计两个覆盖范围,当前这步的最大覆盖 和 下一步的最大覆盖
- 当前这步的最大覆盖
- 当前 数组的【索引】值
- 下一步的最大覆盖
- 当前范围内最大索引值
- 当前这步的最大覆盖
- 统计两个覆盖范围,当前这步的最大覆盖 和 下一步的最大覆盖
- 题解
-
方法一
- 移动下标达到了当前覆盖的最远距离下标时,步数就要加一,来增加覆盖距离。最后的步数就是最少步数。
- 这里还是有个特殊情况需要考虑,当移动下标达到了当前覆盖的最远距离下标时
- 如果当前覆盖最远距离下标不是是集合终点,步数就加一,还需要继续走。
- 如果当前覆盖最远距离下标就是是集合终点,步数不用加一,因为不能再往后走了。
func jump(nums []int) int { if len(nums) < 2 { return 0 } step := 0 //移动的步数 curDistance := 0 nextDistance := 0 for i := 0; i < len(nums); i++ { nextDistance = max(nums[i]+i, nextDistance) //更新下一步最远覆盖距离 if i == curDistance { //到达本次最远覆盖距离 // 此时 i < len(nums) 即 curDistance < len(nums), 还没有走到末尾, 需要继续往前走 step++ curDistance = nextDistance // 更新当前覆盖最远距离下标(相当于加油了) if nextDistance >= len(nums)-1 { //这里用 len(nums)-1 的原因: 走的是索引从0开始 break } } } return step } func max(a, b int) int { if a > b { return a } return b }
-
方法二
- 针对于方法一的特殊情况,可以统一处理,即:移动下标只要遇到当前覆盖最远距离的下标,直接步数加一,不考虑是不是终点的情况。
- 想要达到这样的效果,只要让移动下标,最大只能移动到 nums.size - 2 的地方[倒数第二个数,最终能走一步的地方]就可以了。
- 因为当移动下标指向 nums.size - 2 时:
- 如果移动下标等于当前覆盖最大距离下标, 需要再走一步(即 ans++),因为最后一步一定是可以到的终点【题目要求】。
func jump(nums []int) int { step := 0 curDistance := 0 nextDistance := 0 for i := 0; i < len(nums)-1; i++ { nextDistance = max(nums[i]+i, nextDistance) if i == curDistance { curDistance = nextDistance step++ } } return step } func max(a, b int) int { if a >= b { return a } return b }
- 移动下标达到了当前覆盖的最远距离下标时,步数就要加一,来增加覆盖距离。最后的步数就是最少步数。
-