zoukankan      html  css  js  c++  java
  • 337. 打家劫舍 III

     思路: 考虑每一个节点,小偷有两种选择,偷,或者不偷。

    用res[?, ?]存储这两种情况下能偷到的最多的钱。res[0]表示不偷该节点能得到的最多的钱,res[1]表示偷了该节点能得到的最多的钱。

    1.如果某个节点是NULL,那么显然,res=[0, 0]
    2.如果节点不为空:
      1)不偷此节点的话,其两个子节点偷不偷都可以,对于每个子节点,就看是偷能得到的钱多,还是不偷能拿到的钱多。 

         left表示其左子节点偷或者不偷能得到的最多的钱,right表示其右子节点。那么,res[0] = max(left[0], left[1]) + max(right[0], right[1])

      2)如果偷这个节点,其两个子节点都不能偷。

         用var表示这个节点所拥有的钱,所以,res[1] = var + left[0] + right[0]
    由上述的状态转移公式,每个节点的计算都要用到两个子节点的计算结果,所以要用递归来实现!
    最后,返回root得到的res中,最大的一个,即max(res[0], res[1])

    # Definition for a binary tree node.
    # class TreeNode:
    #     def __init__(self, x):
    #         self.val = x
    #         self.left = None
    #         self.right = None
    
    class Solution:
        def rob(self, root: TreeNode) -> int:
            # 
            def robinteger(root):
                # 如果节点本身就是空的,那无论偷不偷,都拿不到钱
                res = [0, 0]
                if not root: return res
                # res[1]表示节点被偷能拿到的最多的钱
                    # 节点被偷的话,其子节点不能被偷
                left = robinteger(root.left)
                right = robinteger(root.right)
                res[1] += root.val + left[0] + right[0]
                # res[0]表示不偷该节点能拿到的最多的钱
                    # 不被偷的话,无论其子节点是否被偷都可以
                res[0] += max(left[0], left[1]) + max(right[0], right[1])
                return res
            res = robinteger(root)
            return max(res[0], res[1])
    

      

    作者:corch
    链接:https://leetcode-cn.com/problems/house-robber-iii/solution/di-gui-shu-xing-dong-tai-gui-hua-wen-ti-by-corch/
    来源:力扣(LeetCode)

  • 相关阅读:
    python中的赋值与深浅拷贝
    PAT甲级:1089 Insert or Merge (25分)
    PAT甲级:1064 Complete Binary Search Tree (30分)
    navicat 15 破解教程
    SQL
    以初学者的角度理解:SQL实现关系除法
    线性回归与梯度下降(ML作业)
    海明码
    CRC校验原理
    Jupyter notebook总是卡在int[*]怎么解决?
  • 原文地址:https://www.cnblogs.com/USTC-ZCC/p/12689593.html
Copyright © 2011-2022 走看看