Leetcode337. 打家劫舍 III Python

本文探讨了LeetCode问题《House Robber III》的解决策略,通过后序遍历和递归、记忆化搜索以及动态规划的方法,优化了计算小偷在不触动警报情况下能盗取的最大金额。重点讲解了三种方法的时间复杂度和空间复杂度,并提供了实例分析和代码实现。
摘要由CSDN通过智能技术生成

https://leetcode-cn.com/problems/house-robber-iii/
采用后序遍历,主要考察递归和动态规划
参考文献:https://mp.weixin.qq.com/s/BOJ1lHsxbQxUZffXlgglEQ

如果两个直接相连的房子在同一天晚上被打劫,房屋将自动报警。计算在不触动警报的情况下,小偷一晚能够盗取的最高金额。
相邻层数的父子节点不可全部选择,求树节点的最大之和。

输入: [3,4,5,1,3,null,1]

     3
    / \
   4   5
  / \   \ 
 1   3   1

输出: 9
解释: 小偷一晚能够盗取的最高金额 = 4 + 5 = 9.

暴力递归


class Solution(object):
    def rob(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """

        def dfs(root):
            if(not root):
                return 0
            if(not root.left and not root.right):
                return root.val


			#偷父节点
            val1=root.val
            if(root.left):
                val1+=dfs(root.left.left)+dfs(root.left.right)
            if(root.right):
                val1+=dfs(root.right.left)+dfs(root.right.right)
            #不偷父节点
            val2=dfs(root.left)+dfs(root.right)

            return max(val1,val2)
        return dfs(root)

时间复杂度:O(n^2) 这个时间复杂度不太标准,也不容易准确化,例如越往下的节点重复计算次数就越多
空间复杂度:O(n) 算上递推系统栈的空间

记忆化递推


class Solution(object):
    def rob(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        umap={}
        def dfs(root):
            if(not root):
                return 0
            if(not root.left and not root.right):
                return root.val
            if(root in umap): return umap[root]

			#偷父节点
            val1=root.val
            if(root.left):
                val1+=dfs(root.left.left)+dfs(root.left.right)
            if(root.right):
                val1+=dfs(root.right.left)+dfs(root.right.right)
            #不偷父节点
            val2=dfs(root.left)+dfs(root.right)
            umap[root] = max(val1,val2)
            return max(val1,val2)
        return dfs(root)

umaps用于记录中间结果。
时间复杂度:O(n)
空间复杂度:O(n) 算上递推系统栈的空间

动态规划

用两个值存储当前节点偷和不偷的状态结果。

    def rob(self, root):
       """
       :type root: TreeNode
       :rtype: int
       """
       def dp_fun(root):
           if(not root):
               return [0,0]
           left = dp_fun(root.left)
           right = dp_fun(root.right)
   		#偷当前节点
           val1=root.val+left[0]+right[0]
           #不偷当前节点  如果不偷当前节点,那么左右孩子就可以偷,
           #至于到底偷不偷一定是选一个最大的,所以:val2 = max(left[0], left[1]) + max(right[0], right[1]);
           
           val2=max(left[0],left[1])+max(right[1],right[0])
           return [val2,val1]
       return max(dp_fun(root))

时间复杂度:O(n) 每个节点只遍历了一次
空间复杂度:O(n) 算上递推系统栈的空间

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值