leetcode198 打家劫舍

117 阅读1分钟

198. 打家劫舍 - 力扣(LeetCode)

解题思路:分析题目中会发现,计算当前nums[i]获取到最多的金额 要依赖前nums[i-1]获取的最多的金额和nums[i-2]获取最多的金额

实现1:采用递归实现 每次调用的时候都用preval表示nums[i-2]获取到的最多金额,curval表示 [i-1]获取到的最大金额 当i不断的增加后,通过下面的语句,重新计算preval,curval的值 [preval,curval]=[curval,Math.max(curval,preval+nums[i])]

/**
 * @param {number[]} nums
 * @return {number}
 */
var rob = function(nums) {
    let len = nums.length
    if (len == 1) return nums[0]
    let res = 0
    let fn = (index, preval, curval) => {
        if (index == len) {
            // console.log('cur', curval)
            res = curval
            return curval
        } else {
            // console.log(preval, curval, '===', nums[index], preval + nums[index]);
            [preval, curval] = [curval, Math.max(curval, preval + nums[index])];
            fn(index + 1, preval, curval)
        }
    }
    //入口:从三个元素开始,
    fn(2, nums[0], Math.max(nums[0], nums[1]))
    return res
};

实现2:采用dp实现 一:首先定义dp数组和dp[i]表示的含义 dp[i]表示的是前i个元素获取到的最多金额 二:确定递归公式 即找出dp元素之前的关系 dp[i]=Math.max(dp[i-1], dp[i-2]+nums[i]) 三:确定初始值 四:确定遍历顺序

/**
 * @param {number[]} nums
 * @return {number}
 */
var rob = function (nums) {
    let len = nums.length
    // let dp = new Array(len + 1).fill(0)
    // dp[0] = 0
    // dp[1] = nums[0]
    // for (let i = 2; i <= len; i++) {
    //     dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i - 1])
    // }
    // return dp[len]
    let dp = new Array(len).fill(0)
    dp[0] = nums[0], dp[1] = Math.max(nums[0], nums[1])
    for (let i = 2; i < len; i++) {
        dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i])
    }
    return dp[len - 1]
};

let nums = [1, 2, 3, 1]
nums = [2, 7, 9, 13, 1, 1, 10]
nums = [2, 1, 1, 2]
nums = [1, 2]
nums = [2, 1]
nums = [1]
console.log(rob(nums))