代码随想录算法训练营第三十九天| 198.打家劫舍 、 213.打家劫舍II 、 337.打家劫舍III

39 阅读1分钟

198.打家劫舍

相关链接:题目链接文章讲解 视频讲解

解题思路

代码实现

const rob = nums => {
    // 数组长度
    const len = nums.length;
    // dp数组初始化
    //  dp[i]: 前i个房屋能偷到的最大金额
    const dp = [nums[0], Math.max(nums[0], nums[1])];
    // 从下标2开始遍历
    for (let i = 2; i < len; i++) {
        dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]);
    }
    return dp[len - 1];
};

213.打家劫舍II

相关链接:题目链接文章讲解 视频讲解

解题思路

代码实现

var rob = function(nums) {
    if(nums.length===1) return nums[0];
    var max1 = rob2(nums.slice(0,nums.length-1));
    var max2 = rob2(nums.slice(1));
    return Math.max(max1,max2);
};

const rob2 = nums => {
    // 数组长度
    const len = nums.length;
    // dp数组初始化
    //  dp[i]: 前i个房屋能偷到的最大金额
    const dp = [nums[0], Math.max(nums[0], nums[1])];
    // 从下标2开始遍历
    for (let i = 2; i < len; i++) {
        dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]);
    }
    return dp[len - 1];
};

337.打家劫舍III

相关链接:题目链接文章讲解 视频讲解

解题思路

代码实现

const rob = root => {
    // 后序遍历函数
    const postOrder = node => {
        // 递归出口
        if (!node) return [0, 0];
        // 遍历左子树
        const left = postOrder(node.left);
        // 遍历右子树
        const right = postOrder(node.right);
        // 不偷当前节点,左右子节点都可以偷或不偷,取最大值
        const DoNot = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
        // 偷当前节点,左右子节点只能不偷
        const Do = node.val + left[0] + right[0];
        // [不偷,偷]
        return [DoNot, Do];
    };
    const res = postOrder(root);
    // 返回最大值
    return Math.max(...res);
};