基础款
- 确定dp数组(dp table)以及下标的含义
dp[i]:考虑下标i(包括i)以内的房屋,最多可以偷窃的金额为dp[i] 。
-
即dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);
-
dp[0] 一定是 nums[0],dp[1]就是nums[0]和nums[1]的最大值即:dp[1] = max(nums[0], nums[1]);
-
顺序从前到后
func rob(nums []int)int {
if len(nums) == 0{
return 0
}
if len(nums) == 1{
return nums[0]
}
if len(nums) == 2{
return max(nums[0],nums[1])
}
dp := make([]int,len(nums))
dp[0] = nums[0]
for i:=2;i<len(nums);i++{
dp[i] = max(dp[i-1],dp[i-2]+nums[i])
}
return dp[len(nums)-1]
}
func max(a, b int) int {
if a>b{
return a
}
return b
}
围成一个圈
分两种情况,一个包括首不包括尾,一个包括尾不包括首
func rob(nums []int) int {
if len(nums) == 1{
return nums[0]
}
if len(nums)==2 {
return max(nums[0],nums[1])
}
return max(robrange(nums,0,len(nums)-2),robrange(nums,1,len(nums)-1))
}
func robrange(nums []int,start,end int)int{
dp := make([]int,len(nums))
dp[start] = nums[start]
dp[start+1] = max(nums[start],nums[start+1])
for i:= start+2;i<=end;i++{
dp[i] = max(dp[i-1],dp[i-2]+nums[i])
}
return dp[end]
}
func max(a, b int) int {
if a>b{
return a
}
return b
}
树
后序遍历
dp = []int{不偷,偷}
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func rob(root *TreeNode) int {
//0代表没偷金额,1代表偷了
res := []int{}
var rotree func(root *TreeNode)[]int
rotree = func(root *TreeNode)[]int{
if root == nil{
return []int{0,0}
}
left := rotree(root.Left)
right := rotree(root.Right)
//butou
notrobcur := max(left[0],left[1])+max(right[0],right[1])
//tou
robcur:=root.Val+left[0]+right[0]
return []int{notrobcur,robcur}
}
res = rotree(root)
return max(res[0],res[1])
}
func max(a, b int) int {
if a > b {
return a
}
return b
}