答案代码从1开始的,不用看了。
Go
func rob(nums []int) int {
n := len(nums)
dp := make([]int, n)
dp[0] = nums[0]
if n == 1 {
return nums[0]
}
dp[1] = max(nums[0], nums[1])
for i := 2; i < n; i++ {
dp[i] = max(dp[i-2]+nums[i], dp[i-1])
}
return dp[n-1]
}
- 情况一:偷中间,不偷首尾
- 情况二:偷中间+首或尾
- 情况二其实包含了情况一,因为dp[i]的含义是考虑i,不一定非得偷i
Go
// 把环形问题化解成线性问题
func rob(nums []int) int {
if len(nums) == 1 {
return nums[0]
}
resWithHead := robLine(nums[:len(nums)-1])
resWithTail := robLine(nums[1:])
return max(resWithHead, resWithTail)
}
func robLine(nums []int) int {
n := len(nums)
dp := make([]int, n)
dp[0] = nums[0]
if n == 1 {
return nums[0]
}
dp[1] = max(nums[0], nums[1])
for i := 2; i < n; i++ {
dp[i] = max(dp[i-2]+nums[i], dp[i-1])
}
return dp[n-1]
}
数组是每个元素(int类型)有两个状态;同理,二叉树是每个结点(struct类型)有两个状态。
数组中dp[i]值 是 前几个元素的dp值 dp[i-1]和dp[i-2] ...的状态转移;二叉树中dpNode是子节点dpLeft和dpRight的状态转移,只不过dpNode是 有两个状态的数组。