层序遍历?信息差!

题目

二叉树的堂兄弟节点Ⅱ

给你一棵二叉树的根 root ,请你将每个节点的值替换成该节点的所有堂兄弟节点值的和 。

如果两个节点在树中有相同的深度且它们的父节点不同,那么它们互为 堂兄弟

请你返回修改值之后,树的根 root

注意,一个节点的深度指的是从树根节点到这个节点经过的边数。

结论

层序遍历习惯性只从本层考虑,所以试图找到同层两个节点的最近公共祖先 pre判断pre是否是这两个节点的父节点,再做其他处理;不清楚还有哪些优化的空间,但是发现如果是同层去探索同层,难以获取信息,就好像我们一直处在某个阶段想要看清一些层内的事实,需要付出巨大的努力并且不一定有回报,因为上层对我们在一定程度上进行了封锁。
本题解法:同层去处理下层的节点,因为同层掌握了下层的任何事实,此为信息差。

法1 找祖先节点,超时

class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        if root is None or root is p or root is q:
            return root
        l = self.lowestCommonAncestor(root.left, p, q)
        r = self.lowestCommonAncestor(root.right, p, q)
        if l and r:
            return root
        elif l:
            return l
        return r

    def replaceValueInTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        if root is None:
            return root
        queue = deque([root])
        while queue:
            nodes = []
            for _ in range(len(queue)):
                node = queue.popleft()
                nodes.append(node)
                if node.left: queue.append(node.left)
                if node.right: queue.append(node.right)
            if len(nodes) == 1:
                nodes[0].val = 0
            else:
                s = 0
                for n in nodes:
                    s += n.val
                should = [0] * len(nodes)
                for i in range(len(nodes)):
                    if i == 0:
                        pre = self.lowestCommonAncestor(root, nodes[i], nodes[i+1])
                        if pre.left is not nodes[i]:
                            should[i] = s - nodes[i].val
                        else:
                            should[i] = s - nodes[i].val - nodes[i+1].val
                    elif i == len(nodes) - 1:
                        pre = self.lowestCommonAncestor(root, nodes[i], nodes[i-1])
                        if pre.left is not nodes[i-1]:
                            should[i] = s - nodes[i].val
                        else:
                            should[i] = s - nodes[i].val - nodes[i-1].val
                    else:
                        pre = self.lowestCommonAncestor(root, nodes[i], nodes[i-1])
                        pre2 = self.lowestCommonAncestor(root, nodes[i], nodes[i+1])
                        tmp = s - nodes[i].val
                        if pre.left is nodes[i-1]:
                            tmp -= nodes[i-1].val
                        if pre2.left is nodes[i]:
                            tmp -= nodes[i+1].val
                        should[i] = tmp
                for i in range(len(nodes)):
                    nodes[i].val = should[i]
        return root 

法2 信息差

class Solution:
    def replaceValueInTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        if root is None:
            return root
        queue = deque([root])
        root.val = 0
        while queue:
            s = 0
            tmp = []
            for _ in range(len(queue)):
                node = queue.popleft()
                tmp.append(node)
                if node.left:
                    s += node.left.val 
                    queue.append(node.left)
                if node.right: 
                    s += node.right.val
                    queue.append(node.right)
            for node in tmp:
                k = s
                if node.left: k -= node.left.val
                if node.right: k -= node.right.val
                if node.left: node.left.val = k
                if node.right: node.right.val = k
        return root

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值