代码随想录day28|122买股票最佳时机II55跳跃游戏45跳跃游戏II|01笔记

136 阅读2分钟
  • 122买股票最佳时机

  • 代码随想录 (programmercarl.com)
  • 第一印象

  • 寻找所有的单调增区间,并且记录区间的两界并计算差值,最后相加获得总利润
  • 讲解观后感

  • 把利润分解到每天的想法让题目简单了许多。这也体现出了贪心的巧妙。
  • 解题代码

  • 贪心:
  •     func maxProfit(prices []int) int {
            var sum int
            for i := 1; i < len(prices); i++ {
                // 累加每次大于0的交易
                if prices[i] - prices[i-1] > 0 {
                    sum += prices[i] - prices[i-1]
                }
            }
            return sum
        }
    
  • 动态规划:
  •     func maxProfit(prices []int) int {
            dp := make([][]int, len(prices))
            for i := 0; i < len(dp); i++ {
                dp[i] = make([]int, 2)
            }
            // dp[i][0]表示在状态i不持有股票的现金,dp[i][1]为持有股票的现金
            dp[0][0], dp[0][1] = 0, -prices[0]
            for i := 1; i < len(prices); i++ {
                dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i])
                dp[i][1] = max(dp[i-1][0] - prices[i], dp[i-1][1])
            }
            return dp[len(prices)-1][0]
            
        }
        func max(a, b int) int {
            if a > b {
                return a
            }
            return b
        }
    
  • 55跳跃游戏

  • 代码随想录 (programmercarl.com)
  • 第一印象

  • 尝试了从头开始遍历,每一个数字的下标和其本身的和代表着我们能走到的位置,每次将和进行比较并存储,能够遍历到最后则代表成功。
  • 解题代码为:
  •     func canJump(nums []int) bool {
            mx := nums[0]
            for i:=0;i<=mx&&i<len(nums);i++ {
                step := i + nums[i]
                mx = max(step, mx)
            }
            return mx>=(len(nums)-1)
        }
        
        func max(x int, y int) int {
            if x > y {
                return x
            } else {
                return y
            }
        }
    
  • 讲解观后感

  • 在标识符取名方面,cover一次更好的代表了最远可覆盖的含义。
  • 解题代码

  • 一遇到达成条件的cover便直接返回结果,就不用设置len(nums)-1的边界了
  •     // 贪心
        func canJump(nums []int) bool {
            cover := 0
            n := len(nums)-1
            for i := 0; i <= cover; i++ { // 每次与覆盖值比较
                cover = max(i+nums[i], cover) //每走一步都将 cover 更新为最大值
                if cover >= n {
                    return true
                }
            }
            return false
        }
        func max(a, b int ) int {
            if a > b {
                return a
            }
            return b
        }
    
  • 45跳跃游戏II

  • 代码随想录 (programmercarl.com)
  • 讲解观后感

  • 自己第一遍看的时候实在是没有思路。于是直接看了题解。
  • 本题贪心的原因就是因为我们尽量保留当前覆盖范围的cover,当前范围内走不到终点时,我们再使步数+1.这就需要我们维护当前的cover和下一步的cover。
  • 解题代码

  • 贪心一
  •     func jump(nums []int) int {
            n := len(nums)
            if n == 1 {
                return 0
            }
            cur, next := 0, 0
            step := 0
            for i := 0; i < n; i++ {
                next = max(nums[i]+i, next)
                if i == cur {
                    if cur < n-1 {
                        step++
                        cur = next
                        if cur >= n-1 {
                            return step
                        }
                    } else {
                        return step
                    }
                }
            }
            return step
        }
        
        func max(a, b int) int {
            if a > b {
                return a
            }
            return b
        }
    
  • 贪心二
  • 其精髓在于控制移动下标i只移动到len(nums)-2 的位置,所以移动下标只要遇到当前覆盖最远距离的下标,直接步数加一,不用考虑别的了。
  •     // 贪心版本二
        func jump(nums []int) int {
            n := len(nums)
            if n == 1 {
                return 0
            }
            cur, next := 0, 0
            step := 0
            for i := 0; i < n-1; i++ {
                next = max(nums[i]+i, next)
                if i == cur {
                    cur = next
                    step++
                }
            }
            return step
        }
        
        func max(a, b int) int {
            if a > b {
                return a
            }
            return b
        }