1. 动态规划经典问题:打家劫舍系列解析
今天我们来拆解算法训练中经典的打家劫舍问题系列,包含三个不同变种:线性排列(198题)、环形排列(213题)和二叉树结构(337题)。这三个问题层层递进,是掌握动态规划思想不可多得的练手案例。
作为算法工程师,这类问题在实际业务中经常变形出现。比如风控系统中的异常交易检测、游戏中的资源最优收集路径等场景,本质上都是类似的决策过程。下面我将结合自己刷题和面试的经验,带大家系统掌握这三个问题的解法套路。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 基础版:线性房屋排列(198题)
2.1 问题描述与建模
给定一个非负整数数组nums,表示沿街排列的房屋中的金额。相邻房屋装有联动的报警系统,如果两间相邻的房屋在同一晚被打劫,系统会自动报警。求在不触发警报的情况下,能够盗取的最高金额。
示例:
输入:[2,7,9,3,1]
输出:12(选择第1、3、5号房屋)
2.2 动态规划解法
这是最基础的动态规划问题,定义dp[i]表示前i间房屋能获得的最大金额:
python复制def rob(nums):
if not nums:
return 0
n = len(nums)
if n == 1:
return nums[0]
dp = [0] * n
dp[0] = nums[0]
dp[1] = max(nums[0], nums[1])
for i in range(2, n):
dp[i] = max(dp[i-1], dp[i-2] + nums[i])
return dp[-1]
关键点:
- 状态转移方程:dp[i] = max(不抢当前房屋=dp[i-1], 抢当前房屋=dp[i-2]+nums[i])
- 边界条件处理:当房屋数≤2时的特殊情况
实际编码时可以优化空间复杂度到O(1),只需维护前两个状态即可
2.3 常见错误与调试
- 忘记处理空数组或单元素数组的特殊情况
- 错误地将dp数组初始化为nums的拷贝
- 循环起始位置错误(应从索引2开始)
3. 进阶版:环形房屋排列(213题)
3.1 问题变化与拆解
现在房屋
