题目
给你一棵二叉树的根 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