Day39 - 动态规划 Part07

29 阅读1分钟

基础

刷题

  1. 打家劫舍

leetcode.cn/problems/ho…

image.png

动规五部曲:

  1. 确定dp数组含义: 从nums[0:i+1]的家里,找到能够偷的最多的钱是dp[i]

  2. 确定dp数组的递推公式: dp[i] = max(dp[i-1], dp[i-2]+nums[i])

  3. 确定dp数组初始化: dp[0] = nums[0] dp[1] = max(nums[0], nums[1])

  4. 确定dp数组遍历顺序: 从左到右

  5. 打印dp数组

  6. 打家劫舍II

leetcode.cn/problems/ho…

image.png

和第一题的区别是有了一个环形问题,dp数组含义有变化:

dp[i] = []int {包括nums[0]的最大值 , 不包括0的最大值}

最终推导出能偷到最大价值 = max(dp[last-1][0],dp[last-2][1])

好理解的版本:

把环形的打家劫舍分为三种情况:

image.png

因为情况二和情况三都是寻找最大的价值,所以情况一被后面2个包含了。 所以只需要考虑将nums[0:last-1] 和nums[1:last],将这两种情况导入到第一个题的函数中,取最大值

image.png

image.png

  1. 打家劫舍III

leetcode.cn/problems/ho…

image.png

动规五部曲:

  1. 确定dp数组含义: dp[0] 代表 偷该节点能偷到的最大价值, dp[1] 代表不偷该节点能偷到的最大价值

  2. 确定dp数组递推公式
    dp[0] = left[1] + right[1] + node.Val dp[1] = max(left[0], left[1]) + max(right[0], right[1])

  3. 确定dp数组初始化

    dp = []int{0, 0}

  4. 确定dp数组遍历顺序 后序遍历

  5. 打印dp数组

总结

多种情况可以优化为,减少if

switch len(nums) {
        case 0: return 0
        case 1: return nums[0]
    }

slices.Max() 取切片中的最大值

notRobCur := slices.Max(left) + slices.Max(right)