今日算法随笔:填充每个节点的下一个右侧节点指针 II
题目描述
给定一个二叉树,填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。初始状态下,所有 next 指针都被设置为 NULL。
示例:
输入:root = [1,2,3,4,5,null,7]
输出:[1,#,2,3,#,4,5,7,#]
解释:按层序遍历,'#' 表示每一层的末尾。
思路
层次遍历
这道题的核心是按层次遍历二叉树,并将每一层的节点通过 next 指针连接起来。由于树的结构不一定是完美二叉树,每个节点的左右子树数量可能不同,导致每层节点数量不均匀。因此,我们不能简单地直接使用完全二叉树的解法,而是需要根据当前节点的左右子节点来动态连接它们。
解题过程
方法运用
我们需要逐层遍历二叉树并构建 next 指针。在遍历时,使用以下几点策略:
从左到右遍历当前层节点:
- 对于每个节点,我们检查它是否有左子节点和右子节点。如果存在子节点,依次连接它们。
使用
next指针帮助跨节点连接:- 在跨越同一层不同父节点时(即当前节点的右子节点和下一个节点的左子节点),可以利用上一层已经构建好的
next指针,来顺利访问该层的其他节点。
- 在跨越同一层不同父节点时(即当前节点的右子节点和下一个节点的左子节点),可以利用上一层已经构建好的
构建下一层的连接关系:
- 遍历当前层时,将下一层的节点依次连接起来,并通过虚拟节点
dummy来指向下一层的第一个节点。
- 遍历当前层时,将下一层的节点依次连接起来,并通过虚拟节点
遍历完一层后进入下一层:
- 处理完当前层后,我们通过
dummy.next找到下一层的第一个节点,然后继续处理这一层,直到所有层遍历完毕。
- 处理完当前层后,我们通过
代码实现
下面是该算法的完整 Java 实现:
class Solution {
public Node connect(Node root) {
if (root == null) {
return null;
}
// 从当前层的头开始
Node currentLevel = root;
while (currentLevel != null) {
Node dummy = new Node(0); // 虚拟头节点,方便处理下一层的连接
Node prev = dummy; // 用来连接下一层节点的指针
Node curr = currentLevel; // 当前层的节点
while (curr != null) {
if (curr.left != null) {
prev.next = curr.left;
prev = prev.next;
}
if (curr.right != null) {
prev.next = curr.right;
prev = prev.next;
}
curr = curr.next; // 移动到当前层的下一个节点
}
currentLevel = dummy.next; // 进入下一层
}
return root;
}
}
代码细节
Node类:Node类代表二叉树的节点,每个节点包含val(节点值),left(左子节点),right(右子节点)和next(右侧节点的指针)。
主逻辑:
currentLevel变量用于追踪每一层的开始节点。- 通过
dummy虚拟节点和prev指针将下一层的节点按顺序连接起来。 - 遍历完当前层后,
dummy.next就会指向下一层的第一个节点,赋值给currentLevel以开始处理下一层。
循环控制:
- 内层
while (curr != null)循环用于遍历当前层的所有节点,并连接它们的子节点。 - 外层
while (currentLevel != null)循环用于逐层处理,直到所有节点都完成连接。
- 内层
常见问题解答
1. 为什么 currentLevel = dummy.next 能进入下一层?
dummy 是一个虚拟头节点,它用于帮助我们方便地连接当前层的子节点,即下一层的所有节点。当遍历当前层时,每次找到一个子节点,就把它连接到 dummy 的链表中(由 prev.next 来完成)。因此,dummy.next 最终会指向下一层的第一个节点。通过 currentLevel = dummy.next,我们就能顺利进入下一层的第一个节点,开始处理下一层。
2. 为什么需要 dummy 节点?
dummy 节点的作用是简化逻辑。在处理下一层节点时,我们需要将它们串起来,并且要记录下一层的第一个节点。使用 dummy 节点可以方便地处理这种情况,它始终指向下一层的开始位置,无需特殊处理第一个节点与其他节点的连接,简化了代码。
3. 该算法的时间和空间复杂度如何?
- 时间复杂度:O(n),因为每个节点只会被访问一次。
- 空间复杂度:O(1),除了递归栈之外,使用的额外空间是常数级别的。
今日算法随笔:填充每个节点的下一个右侧节点指针 II的更多相关文章
- [leetcode-117]填充每个节点的下一个右侧节点指针 II
(1 AC) 填充每个节点的下一个右侧节点指针 I是完美二叉树.这个是任意二叉树 给定一个二叉树 struct Node { int val; Node *left; Node *right; Nod ...
- [LeetCode] 116. 填充每个节点的下一个右侧节点指针
题目链接 : https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node/ 题目描述: 给定一个完美二叉树 ...
- Java实现 LeetCode 117 填充每个节点的下一个右侧节点指针 II(二)
117. 填充每个节点的下一个右侧节点指针 II 给定一个二叉树 struct Node { int val; Node *left; Node *right; Node *next; } 填充它的每 ...
- Java实现 LeetCode 116 填充每个节点的下一个右侧节点指针
116. 填充每个节点的下一个右侧节点指针 给定一个完美二叉树,其所有叶子节点都在同一层,每个父节点都有两个子节点.二叉树定义如下: struct Node { int val; Node *left ...
- LeetCode OJ:Populating Next Right Pointers in Each Node II(指出每一个节点的下一个右侧节点II)
Follow up for problem "Populating Next Right Pointers in Each Node". What if the given tre ...
- 117. 填充每个节点的下一个右侧节点指针 II
Q: 给定一个二叉树 struct Node { int val; Node *left; Node *right; Node *next; } 填充它的每个 next 指针,让这个指针指向其下一个右 ...
- leetcode117. 填充每个节点的下一个右侧节点指针 II
给定一个二叉树struct Node { int val; Node *left; Node *right; Node *next;}填充它的每个 next 指针,让这个指针指向其下一个右侧节 ...
- leetcode 117. 填充每个节点的下一个右侧节点指针 II(二叉树,DFS)
题目链接 https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node-ii/ 题目大意 给定一个二叉树 s ...
- 【LeetCode】116. 填充每个节点的下一个右侧节点指针 Populating Next Right Pointers in Each Node 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 日期 题目地址:https://leetcode ...
- leetcode 116填充每个节点的下一个右侧节点指针
time O(n) ,sapce O(n) /* // Definition for a Node. class Node { public: int val; Node* left; Node* r ...
随机推荐
- 基于 Impala 的高性能数仓实践之物化视图服务
本文将主要介绍 NDH Impala 的物化视图实现. 接上篇,前两篇分别讲了执行引擎和虚拟数仓,它们是让一个 SQL 又快又好地执行的关键.但如果某些 SQL 过于复杂,比如多张大表进行 Join ...
- oeasy教您玩转vim - 62 - # 缓冲buffer
编辑过程 回忆上次 我们这次了解了编辑过程 默认有一个替换文件swap 修改的内容会保存到一个swap文件 如果swp已经存在 会有个swo文件 以此类推 替换文件可以进行对源文件的修复 没保存到 ...
- 硬件开发笔记(二十八):TPS54331电源设计(一):5V电源供电原理图设计
前言 电源供电电路设计很重要,为了更好的给对硬件设计有需求的人,特意将电源设计的基础过程描述出来. 本篇描述设计常用的12V转5V电路3A. TPS54331(DC-DC稳压器) 概述 ...
- 记hashmap
hashmap是map接口的一个实现类,在同步的情况下hashmap的性能是比较好的 hashmap就是一个kv键值对的集合,将数值散列均匀的存储在哈希表中.插入方法为map.put(k,v),读取方 ...
- mysql中的隐式转换导致全表扫描
mysql中的隐式转换导致全表扫描 在mysql查询中,当查询条件左右两侧类型不匹配的时候会发生隐式转换,可能导致查询无法使用索引.下面分析两种隐式转换的情况 看表结构 phone为 int类型,na ...
- [python] 启发式算法库scikit-opt使用指北
scikit-opt是一个封装了多种启发式算法的Python代码库,可以用于解决优化问题.scikit-opt官方仓库见:scikit-opt,scikit-opt官网文档见:scikit-opt-d ...
- docker无法安装而需要的换源需求
docker无法安装镜像而需要的换源需求: 报错信息 (超时连接) 第一步: 登录阿里云:https://www.aliyun.com/ 第二步: 进入阿里云镜像加速: 点击"控制台&quo ...
- 【Excel】VBA编程 02 访问MySQL数据库
1.配置Windows连接驱动ODBC 因为是访问MySQL,则对应的ODBC驱动由MySQL厂商发布 https://dev.mysql.com/downloads/connector/odbc/ ...
- 【JavaScript】下滑线命名转驼峰命名处理
同事写接口返回的JSON属性名称始终不一致,一会下划线一会驼峰 然后自己封装了一个: function toHump(name){ var newName = name.toLowerCase(); ...
- 基于Unity开发的强化学习环境(游戏环境):ml-agents —— Unity ML-Agents
介绍: https://medium.com/nerd-for-tech/an-introduction-to-machine-learning-with-unity-ml-agents-af7193 ...