打家劫舍问题

198. 打家劫舍

题目

var rob = function(nums) {
    // 1、dp[i]表示偷前i家的最高金额
    const n = nums.length
    const dp = new Array(n+1)

    // 2、初始化dp,dp[0] dp[1]
    dp[0] = 0 // 表示偷0家,即没有偷
    dp[1] = nums[0] // 表示偷第一家

    // 3、遍历更新dp数组
    for(let i=2; i<=n; i++){
        // 由于不能偷相邻的,所以偷不偷第i家取决于是偷i-1家,还是偷i-2家。
        // 偷i-1家就不能偷i家,偷i-2家就可以偷i家,取其中产生最大的那个即可
        dp[i] = Math.max(dp[i-1],dp[i-2]+nums[i-1])
    }
    return dp[n]
};

213. 打家劫舍 II

题目
对于环形就是相当于第一个和最后一个房屋不可以同时偷,那么分两种情况,注意需要转换到偷的上面。不偷第一个,相当于偷第2个到偷第n个。不偷第n个,相当于偷第1个到偷第n-1个。取这两种情况的最大。

var rob = function(nums) {
    // 定义两个dp数组,对应两种情况
    const n = nums.length
    const dp1 = new Array(n+1)
    const dp2 = new Array(n+1)

    // 只有一家的时候,就是这家
    if(n==1) return nums[0]

    // 总的标准就是第一家和最后一家不可以同时偷
    // 对于dp1,偷1~n-1家
    dp1[0] = 0
    dp1[1] = nums[0]
    for(let i=2; i<=n-1; i++){
        dp1[i] = Math.max(dp1[i-1],dp1[i-2]+nums[i-1])
    }

    // 对于dp2,偷2~n家
    dp2[1] = 0
    dp2[2] = nums[1]
    for(let i=3; i<=n; i++){
        dp2[i] = Math.max(dp2[i-1],dp2[i-2]+nums[i-1])
    }
    // 拿到这两种情况的最大值
    return Math.max(dp1[n-1],dp2[n])
};

337. 打家劫舍 III

题目
解析

var rob = function(root) {
    // 递归遍历二叉树,每次返回的是一个节点偷或者不偷所得的金钱,两种情况。
    // 即是一个dp数组,长度为2。dp[0]表示不偷节点所得,dp[1]表示偷节点所得。
    var dfs = function(root){
        // 结束条件,节点为空,那么就都是0
        if(!root) return [0,0]

        // 后序遍历,先得到左右节点偷或者不偷所得,dfs返回的就是这个dp
        let left = dfs(root.left)
        let right = dfs(root.right)

        // 根节点的情况,偷或者不偷所得
        const Do = Math.max(left[0],left[1]) + Math.max(right[0],right[1])// 拿到左右的最大情况
        const DoNot = root.val + left[0] + right[0] // 不可以偷左右

        // 返回数组,两种情况
        return [Do,DoNot]
    }
    // 最后返回的是根节点偷或者不偷的状态
    let res = dfs(root)
    return Math.max(res[0],res[1])
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值