LeetCode 865 Smallest Subtree with all the Deepest Nodes

LeetCode 865

这个题目其实就是要求出最大长度的公共parent。 一种方法就是通过递归来找,先从root开始,如果他的左边的高度和右边的高度是一样的,那么最长的paths,分在了左右两边,那么共同节点就是root自己。如果不是,那么就向高的一遍查找。

因为我们要计算数的高度,这里可以稍微做一个优化就是已经计算过的,我们都可以记住,下次直接使用。

    def subtreeWithAllDeepest(self, root: TreeNode) -> TreeNode:
        memo = collections.defaultdict(int)
        def getHeight(node, memo):
            if node == None: return 0
            if node.val not in memo:                
                memo[node.val] = max(getHeight(node.left, memo), getHeight(node.right, memo)) + 1

            return memo[node.val]

        leftHeight = getHeight(root.left, memo)
        rightHeight = getHeight(root.right, memo)

        if leftHeight == rightHeight: 
            return root

        if leftHeight > rightHeight: 
            return self.subtreeWithAllDeepest(root.left)

        return self.subtreeWithAllDeepest(root.right)

代码很简单,但是效率不是很高,其实我们可能多处重复遍历树的一部分。计算高度一次,然后求解又是一次。

另外一个方法就是把所有的最长paths都先求出来,然后找他们最低的parent。一次遍历求出所有的longest paths。

    def subtreeWithAllDeepest(self, root: TreeNode) -> TreeNode:
        if root == None: return None

        longestPaths = []
        
        def getLongestPaths(node, path, paths):
            if node == None: return
            path.append(node)
            if node.left == None and node.right == None:
                if len(paths) == 0:
                    paths.append(path.copy())
                elif len(paths[0]) < len(path):
                    paths.clear()
                    paths.append(path.copy())
                elif len(path) == len(paths[0]):
                    paths.append(path.copy())
            else:
                getLongestPaths(node.left, path, paths)
                getLongestPaths(node.right, path, paths)
            path.pop()

        getLongestPaths(root, [], longestPaths)

        for i in range(len(longestPaths[0]) -1, -1, -1):
            same = True
            candidate = longestPaths[0][i]
            for j in range(1, len(longestPaths)):
                if candidate != longestPaths[j][i]:
                    same = False
                    break
            if same: 
                return candidate

        return root
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值