「这是我参与2022首次更文挑战的第20天,活动详情查看:2022首次更文挑战」。
1.题目
填充每个节点的下一个右侧节点指针 II
给定一个二叉树
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。
初始状态下,所有 next 指针都被设置为 NULL。
进阶: 你只能使用常量级额外空间。 使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。
示例: 输入:root = [1,2,3,4,5,null,7] 输出:[1,#,2,3,#,4,5,7,#] 解释:给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。序列化输出按层序遍历顺序(由 next 指针连接),'#' 表示每层的末尾。
提示:
树中的节点数小于 6000
-100 <= node.val <= 100
思路
这道题希望我们把二叉树各个层的点组织成链表,一个非常直观的思路是层次遍历。树的层次遍历基于广度优先搜索,它按照层的顺序遍历二叉树,在遍历第 ii 层前,一定会遍历完第 i - 1i−1 层。
算法如下:初始化一个队列 qq,将根结点放入队列中。当队列不为空的时候,记录当前队列大小为 nn,从队列中以此取出 nn 个元素并通过这 nn 个元素拓展新节点。如此循环,直到队列为空。我们不难写出这样的代码:
这样做可以保证每次遍历的 nn 个点都是同一层的。我们可以在遍历每一层的时候修改这一层节点的 next 指针,这样就可以把每一层都组织成链表。
代码
var connect = function(root) {
if (root === null) {
return null;
}
const queue = [root];
while (queue.length) {
const n = queue.length;
let last = null;
for (let i = 1; i <= n; ++i) {
let f = queue.shift();
if (f.left !== null) {
queue.push(f.left);
}
if (f.right !== null) {
queue.push(f.right);
}
if (i !== 1) {
last.next = f;
}
last = f;
}
}
return root;
};