【Py/Java/C++三种语言详解】LeetCode每日一题240207【二叉树BFS】LeetCode2641、二叉树的堂兄弟节点II

news2024/11/14 15:31:36

有华为OD考试扣扣交流群可加948025485
可上全网独家的 欧弟OJ系统 练习华子OD、大厂真题
绿色聊天软件戳 od1336了解算法冲刺训练

文章目录

  • 题目链接
  • 题目描述
  • 解题思路
  • 代码
    • Python
    • Java
    • C++
    • 时空复杂度
  • 华为OD算法/大厂面试高频题算法练习冲刺训练

题目链接

LeetCode2641、二叉树的堂兄弟节点II

题目描述

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

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

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

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

示例 1

  • 输入

在这里插入图片描述

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 。

示例 2

在这里插入图片描述

  • 输入:root = [3,1,2]
  • 输出:[0,0,0]
  • 解释:上图展示了初始的二叉树和修改每个节点的值之后的二叉树。 值为 3 的节点没有堂兄弟,所以值修改为 0 。 值为 1 的节点没有堂兄弟,所以值修改为 0 。 值为 2 的节点没有堂兄弟,所以值修改为 0 。

提示

  • 树中节点数目的范围是 [1, 10(5)]
  • 1 <= Node.val <= 10(4)

解题思路

需要考虑到相同层的其他节点的值,很容易想到使用BFS来完成。

本题难点在于,如何高效地将某个节点的所有堂兄弟节点之和cousin_sum算出来。

假设某一层的所有节点和cur_level_sum已知,某个节点node的和其同一个父节点的兄弟的节点和bro_sum已知,那么存在cousin_sum = cur_level_sum - bro_sum成立。可以将node的值修改为cousin_sum

那么问题进一步退化,在BFS过程中,某一个节点node出队时,如何已知cur_level_sumbro_sum

由于在BFS的过程中,每一个节点都会考虑其子节点,显然其子节点的值的和child_sum也是可以迅速算到的。即

child_sum = 0
child_sum += node.left.val  if node.left  else 0
child_sum += node.right.val if node.right else 0    

当node的子节点node.leftnode.right入队时,我们可以将nodechild_sum和子节点一起存入队列中,那么当子节点node.leftnode.right出队时,nodechild_sum就是子节点node.leftnode.rightbro_sum了。

cur_level_sum的计算也是类似的。在某一层节点出队的时候,下一层的总和nxt_level_sum由当前层的所有节点的所有子节点的值求和获得,即可以将所有nodechild_sum叠加得到。那么在遍历到下一层的时候,下一层的cur_level_sum就是上一层的nxt_level_sum了。

上述过程就可以用一次遍历完成node的值的修改了。

代码

Python

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def replaceValueInTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        q = deque()
        q.append([root, root.val])
        nxt_level_sum = root.val
        while q:
            cur_level_sum = nxt_level_sum
            nxt_level_sum = 0
            q_size = len(q)
            for _ in range(q_size):
                # 弹出节点node以及node的兄弟节点和bro_sum
                node, bro_sum = q.popleft()
                # 当前层的和减去node的兄弟和bro_sum,为node的堂兄弟节点和cousin_sum
                cousin_sum = cur_level_sum - bro_sum
                # 将node的值修改为cousin_sum
                node.val = cousin_sum
                # 初始化node的孩子节点的和为child_sum
                child_sum = 0
                # 如果左孩子/右孩子存在,则更新child_sum
                child_sum += node.left.val  if node.left  else 0
                child_sum += node.right.val if node.right else 0     
                # 如果左孩子/右孩子存在,则将子节点和child_sum存入队列中
                # 对于孩子节点node.left或node.right而言,child_sum是他们的兄弟节点和
                if node.left:
                    q.append([node.left, child_sum])
                if node.right:
                    q.append([node.right, child_sum])
                # 更新下一层的节点和nxt_level_sum
                nxt_level_sum += child_sum      
        return root           
            

Java

class Solution {
    public TreeNode replaceValueInTree(TreeNode root) {
        if (root == null) return null;

        Queue<Pair<Integer, TreeNode>> q = new ArrayDeque<>();
        q.offer(new Pair<>(root.val, root));

        int nextLevelSum = root.val;
        int currentLevelSum = 0;
        while (!q.isEmpty()) {
            currentLevelSum = nextLevelSum;
            nextLevelSum = 0;
            int size = q.size();

            for (int i = 0; i < size; ++i) {
                Pair<Integer, TreeNode> pair = q.poll();
                int siblingSum = pair.getKey();
                TreeNode node = pair.getValue();
                int childSum = 0;
                node.val = currentLevelSum - siblingSum;
                if (node.left != null) 
                    childSum += node.left.val;
                if (node.right != null) 
                    childSum += node.right.val;
                if (node.left != null) 
                    q.offer(new Pair<>(childSum, node.left));
                if (node.right != null) 
                    q.offer(new Pair<>(childSum, node.right));

                nextLevelSum += childSum;
            }
        }

        return root;
    }
}

C++

class Solution {
public:
    TreeNode* replaceValueInTree(TreeNode* root) {
        if (root == nullptr) return nullptr;

        queue<pair<int, TreeNode*>> q;
        q.push({root->val, root});

        int nextLevelSum = root->val;
        int currentLevelSum = 0;
        while (!q.empty()) {
            currentLevelSum = nextLevelSum;
            nextLevelSum = 0;
            int size = q.size();

            for (int i = 0; i < size; ++i) {
                auto [siblingSum, node] = q.front();
                q.pop();
                int childSum = 0;
                node->val = currentLevelSum - siblingSum;
                if (node->left != nullptr) 
                    childSum += node->left->val;
                if (node->right != nullptr) 
                    childSum += node->right->val;
                if (node->left != nullptr) 
                    q.push({childSum, node->left});
                if (node->right != nullptr) 
                    q.push({childSum, node->right});

                nextLevelSum += childSum;
            }
        }

        return root;
    }
};

时空复杂度

时间复杂度:O(N)

空间复杂度:O(N)


华为OD算法/大厂面试高频题算法练习冲刺训练

  • 华为OD算法/大厂面试高频题算法冲刺训练目前开始常态化报名!目前已服务100+同学成功上岸!

  • 课程讲师为全网50w+粉丝编程博主@吴师兄学算法 以及小红书头部编程博主@闭着眼睛学数理化

  • 每期人数维持在20人内,保证能够最大限度地满足到每一个同学的需求,达到和1v1同样的学习效果!

  • 60+天陪伴式学习,40+直播课时,300+动画图解视频,300+LeetCode经典题,200+华为OD真题/大厂真题,还有简历修改、模拟面试、专属HR对接将为你解锁

  • 可上全网独家的欧弟OJ系统练习华子OD、大厂真题

  • 可查看链接 大厂真题汇总 & OD真题汇总(持续更新)

  • 绿色聊天软件戳 od1336了解更多

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1437247.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++——stack与queue与容器适配器

1.stack和queue的使用 1.1stack的使用 栈这种数据结构我们应该挺熟了&#xff0c;先入后出&#xff0c;只有一个出口(出口靠栈顶近)嘛 stack的底层容器可以是任何标准的容器类模板或者一些其他特定的容器类&#xff0c;这些容器类应该支持以操作&#xff1a; empty&#xff1…

6-3、T型加减速单片机程序【51单片机+L298N步进电机系列教程】

↑↑↑点击上方【目录】&#xff0c;查看本系列全部文章 摘要&#xff1a;根据前两节内容&#xff0c;已完成所有计算工作&#xff0c;本节内容介绍具体单片机程序流程及代码 一、程序流程图 根据前两节文章内容可知&#xff0c;T型加减速的关键内容是运动类型的判断以及定时…

Nacos安装,服务注册,负载均衡配置,权重配置以及环境隔离

1. 安装 首先从官网下载 nacos 安装包&#xff0c;注意是下载 nacos-server Nacos官网 | Nacos 官方社区 | Nacos 下载 | Nacos 下载完毕后&#xff0c;解压找到文件夹bin&#xff0c;文本打开startup.cmd 修改配置如下 然后双击 startup.cmd 启动 nacos服务&#xff0c;默认…

【AWS】step-functions服务编排

文章目录 step-functionsState machine typeStandard workflowsExpress workflows design skillsError handlingsaga Transaction processing控制分布式系统中的并发性 收费 作为AWS Serverless无服务器的一个重要一环 使用step-functions方法将 AWS 服务链接在一起 step-funct…

阿里云游戏服务器多少钱一个月?

阿里云游戏服务器租用价格表&#xff1a;4核16G服务器26元1个月、146元半年&#xff0c;游戏专业服务器8核32G配置90元一个月、271元3个月&#xff0c;阿里云服务器网aliyunfuwuqi.com分享阿里云游戏专用服务器详细配置和精准报价&#xff1a; 阿里云游戏服务器租用价格表 阿…

Java实现数据可视化的智慧河南大屏 JAVA+Vue+SpringBoot+MySQL

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示四、核心代码4.1 数据模块 A4.2 数据模块 B4.3 数据模块 C4.4 数据模块 D4.5 数据模块 E 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的数据可视化的智慧河南大屏&#xff0c;包含了GDP、…

删除.git的影响、git分支切换时注意事项

一、删除.git的影响 master分支文件 dev分支文件 删除.git后 文件为删除.git前分支的文件状态。 二、git分支切换时注意事项 情景&#xff1a;如果我在分支A&#xff0c;想要跳转到分支B。 git的规矩是&#xff0c;在那个分支上进行的提交&#xff0c;就算哪个分支上的工作…

前端文件下载的多种方式

前端文件下载的多种方式。 前言a标签下载a标签常用属性介绍- target&#xff0c;href&#xff0c;download。 window.location.href下载window.open下载iframe 下载动态生成a标签下载文件url下载文件流下载blob文件流转换常用类型 使用 streamSaver 看实时下载进度 前言 如果我…

【类与对象(中)】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 1.类的6个默认成员函数 2. 构造函数 2.1 概念 2.2 特性 3.析构函数 3.1 概念 3.2 特性 4. 拷贝构造函数 4.1 概念 4.2 特征 引用 常引用 5.赋值运算符重载 5.1…

SpringCloud--Gateway解析

一、Gateway简介 Gateway是Spring Cloud官方推出的第二代微服务网关&#xff0c;它旨在提供统一的路由方式以及为微服务应用提供强大的负载均衡能力。与第一代Spring Cloud Netflix Zuul相比&#xff0c;Spring Cloud Gateway在性能、可扩展性、易用性等方面都有了显著的提升。…

Python深入理解collections模块:常见数据结构及应用场景分析

Python深入理解collections模块&#xff1a;常见数据结构及应用场景分析 介绍collections模块的常见数据结构代码演示defaultdictCounterOrderedDict 介绍 在Python编程中&#xff0c;经常需要使用一些内置的数据结构&#xff0c;如列表、字典等。然而&#xff0c;在某些特定的…

uniapp 本地存储的方式

1. uniapp 本地存储的方式 在uniapp开发中&#xff0c;本地存储是一个常见的需求。本地存储可以帮助我们在客户端保存和管理数据&#xff0c;以便在应用程序中进行持久化存储。本文将介绍uniapp中本地存储的几种方式&#xff0c;以及相关的代码示例。 1.1. 介绍 在移动应用开发…

OSPF综合实验报告

实验要求&#xff1a; 实验预览图&#xff1a; 实验分析&#xff1a; 1、对R4仅仅配置端口IP和环回&#xff0c;使用共有IP 2、对R3-R7配置MGRE环境&#xff0c;以R3为hub&#xff0c;R5、R7、R6为spoke。 3、对172.16.0.0/16 IP进行子网划分&#xff0c;使得全网IP基于该网…

数据结构第十天(排序算法总结)

目录 前言 常数时间复杂度&#xff1a;O(1) 线性时间复杂度&#xff1a;O(n) 线性对数时间复杂度&#xff1a;O(n log n) 平方时间复杂度&#xff1a;O(n^2) 对数时间复杂度&#xff1a;O(log n) 前言 排序算法的学习可以告一段落了。但算法的学习永不停止。 今天&…

用python编写爬虫,爬取二手车信息+实验报告

题目 报告要求 工程报告链接放在这里 https://download.csdn.net/download/Samature/88805518使用 1.安装jupyter notebook 2.用jupyter notebook打开工程里的ipynb文件&#xff0c;再run all就行 注意事项 可能遇到的bug 暂无&#xff0c;有的话私信我

通过dockerfile 生成自定义nginx镜像

通过dockerfile生成自定义nginx镜像 &#xff01;&#xff01;&#xff01;docker 必须在linux环境下才能进行如果你是window则需要装虚拟机 新建一个文件名字为Dockerfile&#xff0c;无需后缀 文件完整名就是Dockerfile 编写dockerfile FROM nginx RUN echo hello nginx!…

golang windows 环境搭建 环境配置

golang windows 环境搭建 环境配置 Golang学习之路一环境搭建 MacBook Linux 树莓派raspberrypi安装Golang环境 官网下载地址: https://go.dev/dl/ https://golang.google.cn/dl/ 下载对应系统版本&#xff0c;例如windows 64位系统&#xff0c;下载&#xff1a;xxx.window…

年终奖,有人欢喜有人忧

每年的年终奖&#xff0c;有人欢喜有人忧&#xff0c;这是科技圈的一种共同现象。最近&#xff0c;科技界最热门的新闻无疑是Meta公布了其Q4和2023年全年财报&#xff0c;被许多人誉为“史上最强财报”。 Meta的股价也从2022年的最低点90美元左右&#xff0c;一路飙升至现在的每…

2024.02.06

TCP提供面向有连接的&#xff0c;可靠的数据传输服务&#xff0c;传输过程中&#xff0c;数据无误、数据无丢失、数据无失序、数据无重复 UDP面向无连接的&#xff0c;不保证数据可靠的&#xff0c;尽最大努力传输的协议&#xff0c;数据传输过程中&#xff0c;可能出现数据丢…

【C++11】统一初始化 和 initializer_list

文章目录 一、概念辨析1. 声明、定义、初始化、赋初值的概念2. 默认初始化 和 未被初始化 的概念 二、C98 的列表初始化三、C11 对列表初始化的扩展&#xff08;统一初始化&#xff09;四、标准库中的 initializer_list 类五、正确理解“统一初始化”和 initializer_list 的区别…