LeetCode题解:198. 打家劫舍,动态规划(不缓存偷盗状态),JavaScript,详细注释

原题链接:198. 打家劫舍

解题思路:

  1. 对于第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]之后的对比都可以省略。
  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];
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值