• 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)

  • 相关阅读:
    c/c++ 网络编程 getaddrinfo 函数
    c/c++ 网络编程 bind函数
    c/c++ socket API 调用后的错误判断 perror errno
    python基础-面向对象编程之反射
    彻底理解Future模式
    Java并发编程:Callable、Future和FutureTask
    java异步调用方法
    理解ThreadLocal
    ReentrantReadWriteLock读写锁
    java锁优化
  • 原文地址:https://www.cnblogs.com/USTC-ZCC/p/12689593.html
Copyright © 2020-2023  润新知