原题链接:198. 打家劫舍
解题思路:
-
对于第i个房子,有两种场景,偷或不偷:
- 如果不偷的话,
dp[i] = dp[i - 1] + 0
- 如果偷的话,那么i之前的所有的可能情况,也就是
dp[i] = Math.max(nums[i] + dp[i - 2], nums[i] + dp[i - 3], ...)
。如此可知,每一位都取了之前所有可能的最大值。那么就可以推导出dp[i - 2] > dp[i - 3] > dp[i - 4]...
,因此dp[i - 2]
之后的对比都可以省略。
- 如果不偷的话,
-
状态转移方程:
dp[i] = Math.max(dp[i - 1] + 0, nums[i] + dp[i - 2])
。
/**
* @param {number[]} nums
* @return {number}
*/
var rob = function (nums) {
// 由于要从前两次的状态开始递推,一次初始化时要创建两个元素,并且都要取最大值
let dp = [
// 偷了第0户
nums[0] || 0,
// 第0和1户只能选一户偷
Math.max(nums[0] || 0, nums[1] || 0),
];
// 从第2户开始递推
for (let i = 2; i < nums.length; i++) {
dp[i] = Math.max(
// 如果不偷第i户,只需考虑i-1户的情况
dp[i - 1],
// 如果偷第i户,需要考虑i-2到0户的情况,而i-2必然大于之前所有结果,此处只需要考虑i-2即可
nums[i] + dp[i - 2],
);
}
// 递推到最后一个值,就是最大偷到的金额
return dp[dp.length - 1];
};