☆打卡算法☆LeetCode 116、 填充每个节点的下一个右侧节点指针 算法解析

简介: “给定一个完美二叉树,填充它的每个next指针,让这个指针指向其下一个右侧节点。”

一、题目


1、算法题目

“给定一个完美二叉树,填充它的每个next指针,让这个指针指向其下一个右侧节点。”

题目链接:

来源:力扣(LeetCode)

链接:   116. 填充每个节点的下一个右侧节点指针


2、题目描述

给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:

struct Node {
  int val;
  Node *left;
  Node *right;
  Node *next;
}
复制代码

填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。

初始状态下,所有 next 指针都被设置为 NULL。

网络异常,图片无法展示
|

示例 1:
输入:root = [1,2,3,4,5,6,7]
输出:[1,#,2,3,#,4,5,6,7,#]
解释:给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。序列化的输出按层序遍历排列,同一层节点由 next 指针连接,'#' 标志着每一层的结束。
复制代码
示例 2:
输入: root = []
输出: []
复制代码


二、解题


1、思路分析

题目的题意是要求我们将二叉树的每一层节点都连接起来形成一个链表。

因此比较直接的方法就是层次遍历,在层次遍历的过程中,将二叉树的每一层节点取出来遍历并链接。

层次遍历基于广度优先搜索算法,广度优先搜索算法每次会取出一个节点来拓展,而层次遍历会每次将队列中的所有元素都拿出来拓展。

层次遍历可以保证每次从队列中拿出来遍历的元素都是基于同一层的。


2、代码实现

代码参考:

class Solution {
    public Node connect(Node root) {
        if (root == null) {
            return root;
        }
        // 初始化队列同时将第一层节点加入队列中,即根节点
        Queue<Node> queue = new LinkedList<Node>(); 
        queue.add(root);
        // 外层的 while 循环迭代的是层数
        while (!queue.isEmpty()) {
            // 记录当前队列大小
            int size = queue.size();
            // 遍历这一层的所有节点
            for (int i = 0; i < size; i++) {
                // 从队首取出元素
                Node node = queue.poll();
                // 连接
                if (i < size - 1) {
                    node.next = queue.peek();
                }
                // 拓展下一层节点
                if (node.left != null) {
                    queue.add(node.left);
                }
                if (node.right != null) {
                    queue.add(node.right);
                }
            }
        }
        // 返回根节点
        return root;
    }
}
复制代码

网络异常,图片无法展示
|


3、时间复杂度

时间复杂度 : O(N)

每个节点都会被访问一次且只会被访问一次,所以时间复杂度为O(N)。

空间复杂度: O(N)

广度优先遍历算法的复杂度取决于一个层级上的最大元素数量,这种情况下空间复杂度为O(N)。


三、总结

当然这一题还可以使用已经建立的next指针。

在一棵树中,存在两种类型的next指针:

  • 连接同一个父节点的两个子节点,可以通过同一个节点访问到。
  • 不同父节点的子节点之间建立连接。

如果每个节点有指向父节点的指针,就可以通过该指针找到next节点。



相关文章
|
13天前
|
存储 算法
算法入门:专题一:双指针(有效三角形的个数)
给定一个数组,找出能组成三角形的三元组个数。利用“两边之和大于第三边”的性质,先排序,再用双指针优化。固定最大边,左右指针从区间两端向内移动,若两短边之和大于最长边,则中间所有组合均有效,时间复杂度由暴力的O(n³)降至O(n²)。
|
6月前
|
机器学习/深度学习 存储 算法
【LeetCode 热题100】347:前 K 个高频元素(详细解析)(Go语言版)
这篇文章详细解析了力扣热题 347——前 K 个高频元素的三种解法:哈希表+小顶堆、哈希表+快速排序和哈希表+桶排序。每种方法都附有清晰的思路讲解和 Go 语言代码实现。小顶堆方法时间复杂度为 O(n log k),适合处理大规模数据;快速排序方法时间复杂度为 O(n log n),适用于数据量较小的场景;桶排序方法在特定条件下能达到线性时间复杂度 O(n)。文章通过对比分析,帮助读者根据实际需求选择最优解法,并提供了完整的代码示例,是一篇非常实用的算法学习资料。
388 90
|
7月前
|
存储 自然语言处理 算法
【LeetCode 热题100】208:实现 Trie (前缀树)(详细解析)(Go语言版)
本文详细解析了力扣热题 208——实现 Trie(前缀树)。Trie 是一种高效的树形数据结构,用于存储和检索字符串集合。文章通过插入、查找和前缀匹配三个核心操作,结合 Go 语言实现代码,清晰展示了 Trie 的工作原理。时间复杂度为 O(m),空间复杂度也为 O(m),其中 m 为字符串长度。此外,还探讨了 Trie 的变种及应用场景,如自动补全和词典查找等。适合初学者深入了解 Trie 结构及其实际用途。
203 14
|
算法 测试技术 C++
【动态规划算法】蓝桥杯填充问题(C/C++)
【动态规划算法】蓝桥杯填充问题(C/C++)
|
算法
Leetcode 初级算法 --- 数组篇
Leetcode 初级算法 --- 数组篇
115 0
|
10月前
|
算法 容器
【算法】——双指针算法合集(力扣)
移动零,复写零,快乐数,盛最多水的容器,有效三角形的个数,和为s的两个数(查找总价格为目标值的两个商品 ),三数之和,四数之和
|
10月前
|
存储 程序员 C++
深入解析C++中的函数指针与`typedef`的妙用
本文深入解析了C++中的函数指针及其与`typedef`的结合使用。通过图示和代码示例,详细介绍了函数指针的基本概念、声明和使用方法,并展示了如何利用`typedef`简化复杂的函数指针声明,提升代码的可读性和可维护性。
274 1
|
11月前
|
存储 算法 Java
leetcode算法题-有效的括号(简单)
【11月更文挑战第5天】本文介绍了 LeetCode 上“有效的括号”这道题的解法。题目要求判断一个只包含括号字符的字符串是否有效。有效字符串需满足左括号必须用相同类型的右括号闭合,并且左括号必须以正确的顺序闭合。解题思路是使用栈数据结构,遍历字符串时将左括号压入栈中,遇到右括号时检查栈顶元素是否匹配。最后根据栈是否为空来判断字符串中的括号是否有效。示例代码包括 Python 和 Java 版本。
244 4
|
12月前
|
算法
每日一道算法题(Leetcode 20)
每日一道算法题(Leetcode 20)
119 2
|
算法 C++
【算法】双指针+二分(C/C++
【算法】双指针+二分(C/C++

推荐镜像

更多
  • DNS