首页 > 编程语言 >今日算法随笔:填充每个节点的下一个右侧节点指针 II

今日算法随笔:填充每个节点的下一个右侧节点指针 II

时间:2024-09-09 10:36:41浏览次数:1  
标签:一层 dummy 遍历 next II 随笔 节点 指针

题目链接:117. 填充每个节点的下一个右侧节点指针 II

题目描述

给定一个二叉树,填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。初始状态下,所有 next 指针都被设置为 NULL

示例

输入:root = [1,2,3,4,5,null,7]
输出:[1,#,2,3,#,4,5,7,#]
解释:按层序遍历,'#' 表示每一层的末尾。

思路

层次遍历

这道题的核心是按层次遍历二叉树,并将每一层的节点通过 next 指针连接起来。由于树的结构不一定是完美二叉树,每个节点的左右子树数量可能不同,导致每层节点数量不均匀。因此,我们不能简单地直接使用完全二叉树的解法,而是需要根据当前节点的左右子节点来动态连接它们。

解题过程

方法运用

我们需要逐层遍历二叉树并构建 next 指针。在遍历时,使用以下几点策略:

  1. 从左到右遍历当前层节点

    • 对于每个节点,我们检查它是否有左子节点和右子节点。如果存在子节点,依次连接它们。
  2. 使用 next 指针帮助跨节点连接

    • 在跨越同一层不同父节点时(即当前节点的右子节点和下一个节点的左子节点),可以利用上一层已经构建好的 next 指针,来顺利访问该层的其他节点。
  3. 构建下一层的连接关系

    • 遍历当前层时,将下一层的节点依次连接起来,并通过虚拟节点 dummy 来指向下一层的第一个节点。
  4. 遍历完一层后进入下一层

    • 处理完当前层后,我们通过 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;
    }
}

代码细节

  1. Node

    • Node 类代表二叉树的节点,每个节点包含 val(节点值),left(左子节点),right(右子节点)和 next(右侧节点的指针)。
  2. 主逻辑

    • currentLevel 变量用于追踪每一层的开始节点。
    • 通过 dummy 虚拟节点和 prev 指针将下一层的节点按顺序连接起来。
    • 遍历完当前层后,dummy.next 就会指向下一层的第一个节点,赋值给 currentLevel 以开始处理下一层。
  3. 循环控制

    • 内层 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),除了递归栈之外,使用的额外空间是常数级别的。

标签:一层,dummy,遍历,next,II,随笔,节点,指针
From: https://www.cnblogs.com/yubaibaibubai/p/18404066

相关文章

  • 一文讲清,常用通信协议IIC,SPI,串口,基于STM32
    目录一、通讯的基本概念1.串行通讯2.并行通讯3.传输模式(单工、半双工、全双工)二、常见通讯协议(串口、IIC、SPI)1.串口(1)UART和USART的区别是什么?(2)UART(TTL、RS232、RS485)(3)基于STM32的HAL库的串口配置2.IIC(1)物理层(2)协议层(3)软件模拟IIC通讯代码(4)有关IIC面试的问题(5)硬......
  • Java毕设项目II基于Spring Boot的在线远程考试系统设计与实现
    目录一、前言二、技术介绍三、系统实现四、论文参考五、核心代码六、源码获取全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末一、前言随着信息技术的飞速发展和教育模式的不断......
  • RocketMQ5部署单节点服务
    关于RocketMQ的单节点部署官方文档已经描述得非常清楚了,这里只是做一个简单的备忘。如下安装步骤均基于最新的ApacheRocketMQ5.3.0实现。下载安装RocketMQ直接下载官方编译后的二进制包到本地并解压。$unziprocketmq-all-5.3.0-bin-release.zip默认情况下,启动RocketMQ至......
  • 华为笔试——输出单向链表中倒数第k个节点
    描述输入一个单向链表,输出该链表中倒数第k个结点,链表的倒数第1个结点为链表的尾指针。链表结点定义如下:struct ListNode{    int m_nKey;    ListNode* m_pNext;};正常返回倒数第k个结点指针,异常返回空指针.要求:(1)正序构建链表;(2)构建后要忘记链表长度......
  • 数据分析实战第一节随笔
    引言Python,作为一种高级编程语言,以其简洁明了的语法和强大的功能库,赢得了全球开发者的广泛青睐。它不仅适用于数据科学、机器学习、人工智能等领域,而且在Web开发、自动化脚本编写、科学计算等方面也发挥着重要作用。本文将带领读者从Python的基础语法开始,逐步深入到实际应用,探索P......
  • 142. 环形链表 II
    给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从0开始)。......
  • 自我评估随笔
    1.自我评估(1)专业知识能力具体描述编程语言基础掌握基本的的编程语言,如c语言、python等,能够较简洁明了的根据需求写出代码,同时刷完了pta乙级的全部题目,对编程语言的掌握相对熟练算法能力自学数据结构与算法,同时也会在csdn等平台进行交流学习,向编程大佬学习一些巧妙......
  • Day07 字符串part01| LeetCode 344. 反转字符串,541. 反转字符串II,卡码网:54.替换数字
    反转字符串344.反转字符串classSolution{publicvoidreverseString(char[]s){intlens=s.length;intright,left;if(lens%2!=0)//奇数个{right=lens/2+1;left=lens/2-1......
  • Day04 链表part02| LeetCode 24. 两两交换链表中的节点,19. 删除链表的倒数第 N 个,160.
    两两交换链表中的节点24.两两交换链表中的节点classSolution{publicListNodeswapPairs(ListNodehead){//设置虚拟头节点ListNodedummy=newListNode(0,head);ListNodecur=dummy;while(cur.next!=null&......
  • ROS - 一个进程中创建多个ROS节点
    文章目录1、概述2、方法1:创建多个命名空间3、方法2:使用多线程4、方法3:节点间通信(分离进程)4、实际验证不可行方案1:两次调用ros::init1、概述在ROS(RobotOperatingSystem)中,每个进程通常只能通过ros::init初始化一个节点。ROS的设计是基于一个进程对应一......