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 0case 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}
}