填充每个节点的下一个右侧节点指针
描述
-
给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:
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 = []
输出:[]
提示
- 树中节点的数量在 [0, 2 12 2^{12} 212 - 1] 范围内
- -1000 <= node.val <= 1000
进阶
- 你只能使用常量级额外空间
- 使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度
Typescript 版算法实现
1 ) 方案1:层次遍历
/**
* Definition for _Node.
* class _Node {
* val: number
* left: _Node | null
* right: _Node | null
* next: _Node | null
* constructor(val?: number, left?: _Node, right?: _Node, next?: _Node) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* this.next = (next===undefined ? null : next)
* }
* }
*/
function connect(root: _Node | null): _Node | null {
if (root === null) {
return root;
}
// 初始化队列同时将第一层节点加入队列中,即根节点
const Q = [root];
// 外层的 while 循环迭代的是层数
while (Q.length > 0) {
// 记录当前队列大小
const size = Q.length;
// 遍历这一层的所有节点
for(let i = 0; i < size; i++) {
// 从队首取出元素
const node = Q.shift();
// 连接
if (i < size - 1) {
node.next = Q[0];
}
// 拓展下一层节点
if (node.left !== null) {
Q.push(node.left);
}
if (node.right !== null) {
Q.push(node.right);
}
}
}
// 返回根节点
return root;
};
2 ) 方案2:使用已建立的 next 指针
/**
* Definition for _Node.
* class _Node {
* val: number
* left: _Node | null
* right: _Node | null
* next: _Node | null
* constructor(val?: number, left?: _Node, right?: _Node, next?: _Node) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* this.next = (next===undefined ? null : next)
* }
* }
*/
// 定义二叉树节点的接口
interface TreeNode {
val: number;
left: TreeNode | null;
right: TreeNode | null;
next: TreeNode | null;
}
function connect(root: TreeNode | null): TreeNode | null {
if (!root) return root;
// 从根节点开始
let leftmost = root;
while (leftmost.left) {
// 遍历这一层节点组织成的链表,为下一层的节点更新 next 指针
let head = leftmost;
while (head) {
// CONNECTION 1
head.left.next = head.right;
// CONNECTION 2
if (head.next) {
head.right.next = head.next.left;
}
// 指针向后移动
head = head.next;
}
// 去下一层的最左的节点
leftmost = leftmost.left;
}
return root;
}
530



被折叠的 条评论
为什么被折叠?



