2641. 二叉树的堂兄弟节点 II - 力扣(LeetCode)

题目描述

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

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

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

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

题目示例

输入:root = [5,4,9,1,10,null,7]
输出:[0,0,0,7,7,null,11]
解释:上图展示了初始的二叉树和修改每个节点的值之后的二叉树。
值为 5 的节点没有堂兄弟,所以值修改为 0 。
值为 4 的节点没有堂兄弟,所以值修改为 0 。
值为 9 的节点没有堂兄弟,所以值修改为 0 。
值为 1 的节点有一个堂兄弟,值为7,所以值修改为7。
值为 10 的节点有一个堂兄弟,值为7,所以值修改为7。
值为 7 的节点有两个堂兄弟,值分别为 1 和 10,所以值修改为 11。

解题思路

题目要求将二叉树中每个节点的值替换为所有堂兄弟节点的和,而堂兄弟节点就是指那些和当前节点深度相同但父节点不同的节点。例如下图中,x 的堂兄弟节点是第 n 层除去 x 和 y 的其他所有节点。假设第 n 层所有节点的和为 sum,那么 x 的值应该被替换为 sum−x−y。
在这里插入图片描述

在广度优先搜索的过程中,通过第 n−1 层去遍历第 n 层的节点时,可以顺便统计第 n 层节点的和 sum。由于更新 x 的值时需要知道 y 的值(有可能不存在),因此需要通过 n−1 层对第 n 层进行第二次遍历,这时就可以使用 sum−x−y 更新 x 的值了。

在代码实现时,我们需要遍历每一层的节点两次,因此使用动态数组或链表表示的队列会更方便。

参考代码

class Solution {
    public TreeNode replaceValueInTree(TreeNode root) {
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        root.val = 0;
        // 通过队列来
        while(!queue.isEmpty()) {
            // 统计下一层的节点,用于遍历
            Queue<TreeNode> queue2 = new LinkedList<>();
            int sum = 0;
            // 遍历 n-1 层时,统计 n 层的总和 sum
            for(TreeNode fa : queue) {
                if(fa.left != null) {
                    queue2.add(fa.left);
                    sum += fa.left.val;
                }
                if(fa.right != null) {
                    queue2.add(fa.right);
                    sum += fa.right.val;
                }
            }
            for(TreeNode fa : queue) {
                // 当前节点的左右孩子节点之和
                int childSum = (fa.left != null ? fa.left.val : 0)
                + (fa.right != null ? fa.right.val : 0);
                // 将左右孩子的值改为 sum-childSum
                if(fa.left != null) {
                    fa.left.val = sum - childSum;
                }
                if(fa.right != null) {
                    fa.right.val = sum - childSum;
                }
            }
            queue = queue2;
        }
        return root;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值