算法【中等-LCR 089. 打家劫舍】

57 阅读2分钟

Hello,大家好,我是disguiseFish,我已经摆烂很长一段时间啦,摆烂的日子过得快乐又飞快~不知不觉都一年多了!!

最近在卷算法,但其实我的逻辑思维能力偏弱以及我之前就没有刷过算法!!所以我决定,每天写一点算法提升自己的逻辑思维!接下来我会从简入深的顺序来卷算法,同时会把看过的算法记录在这个平台~ 共勉!!!

089. 打家劫舍

一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响小偷偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警

给定一个代表每个房屋存放金额的非负整数数组 nums ,请计算 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。

示例 1:

输入: nums = [1,2,3,1]
输出: 4
解释: 偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
     偷窃到的最高金额 = 1 + 3 = 4

示例 2:

输入: nums = [2,7,9,3,1]
输出: 12
解释: 偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
     偷窃到的最高金额 = 2 + 9 + 1 = 12

 

提示:

  • 1 <= nums.length <= 100
  • 0 <= nums[i] <= 400

解决方案

思路: 定义一个空数组 第i项代表i+1之前的最大值 最后输出dp的最后一位之前的最大值即我们要的答案

所以我们可以只遍历一次 算出第i项之前的最大值 然后存入其中

总体思路:

image.png

 
/**
 * @param {number[]} nums
 * @return {number}
 */

var rob = function (nums) {
    // 定义一个空数组  第i项代表i+1之前的最大值  最后输出dp的最后一位之前的最大值即我们要的答案
    let dp = [0]
    dp[0] = nums[0]
    // 如果数组长度只有一项 直接返回第0项
    if(nums.length === 1) return nums[0]
    dp[1] = Math.max(nums[0], nums[1])
    for (let i = 2; i < nums.length; i++) {
        // 根据上面图解 可以 知道 第i项之前的最大值是通过 max(dp[i - 1], dp[i - 2] + nums[i])算的
        //  这里要注意的是 i从第三位算起 
        dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i])
    }
    return dp[dp.length - 1]
};