dp
1、198. 打家劫舍
题目:
输入:[2,7,9,3,1]
输出:12
偷窃到的最高金额 = 2 + 9 + 1 = 12 。
思路:
- 只有两种情况,递推公式就好说了,dp[i]永远都是题意,就是当前偷到的最大金额
func rob(nums []int) int {
// dp,一刷
dp := make([]int, len(nums)+1)
dp[1] = nums[0]
for i:=2; i<=len(nums); i++ {
dp[i] = max(dp[i-1], dp[i-2]+nums[i-1])
}
return dp[len(nums)]
}
func max(a, b int) int {if a>b {return a}; return b}
2、213. 打家劫舍 II
题目:
输入:nums = [2,3,2]
输出:3
解释:你不能先偷窃 1 号房屋(金额 = 2),然后偷窃 3 号房屋(金额 = 2), 因为他们是相邻的。
思路:
- 害,这次是围了个圈圈,就是说明了写两种情况,避免即选择了第一个又选择了最后一个
func rob(nums []int) int {
if len(nums) <= 1 {
return djjs2(nums)
}
res1 := djjs2(nums[:len(nums)-1])
res2 := djjs2(nums[1:])
return max(res1, res2)
}
func djjs2(nums []int) int {
switch len(nums) {
case 0: return 0
case 1: return nums[0]
}
dp := make([]int, len(nums)+1)
dp[1] = nums[0]
for i:=2; i<=len(nums); i++ {
dp[i] = max(dp[i-1], dp[i-2]+nums[i-1])
}
return dp[len(nums)]
}
func max(a,b int) int {if a>b {return a}; return b}
3、337. 打家劫舍 III
题目:
思路:
- 看注释
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func rob(root *TreeNode) int {
// dp 这个确实有一行不好想,需要画图
res := robTree(root)
return max(res[0], res[1])
}
func max(a, b int) int {if a>b {return a}; return b}
func robTree(node *TreeNode) []int {
if node == nil {
return []int{0,0}
}
left := robTree(node.Left)
right := robTree(node.Right)
// 0不偷,1偷
robNode := node.Val + left[0] + right[0] // 当前偷,就要加左右孩子的不偷
notRobNode := max(left[0], left[1])+max(right[0], right[1]) // 当前不偷,前一个可以偷也可以不偷,+最大的
return []int{notRobNode, robNode}
}