代码随想录算法训练营第三十四天 | 198.打家劫舍 213.打家劫舍II 337.打家劫舍III

答案代码从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是 有两个状态的数组。

相关推荐
灵感__idea5 小时前
Hello 算法:贪心的世界
前端·javascript·算法
澈2077 小时前
深入浅出C++滑动窗口算法:原理、实现与实战应用详解
数据结构·c++·算法
ambition202427 小时前
从暴力搜索到理论最优:一道任务调度问题的完整算法演进历程
c语言·数据结构·c++·算法·贪心算法·深度优先
cmpxr_7 小时前
【C】原码和补码以及环形坐标取模算法
c语言·开发语言·算法
qiqsevenqiqiqiqi7 小时前
前缀和差分
算法·图论
代码旅人ing7 小时前
链表算法刷题指南
数据结构·算法·链表
Yungoal7 小时前
常见 时间复杂度计算
c++·算法
不爱吃炸鸡柳8 小时前
单链表专题(完整代码版)
数据结构·算法·链表
CylMK9 小时前
题解:AT_abc382_d [ABC382D] Keep Distance
算法
Dfreedom.9 小时前
计算机视觉全景图
人工智能·算法·计算机视觉·图像算法