题目描述
给定一个二叉树
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 所示。
提示:
树中的节点数小于 6000
-100 <= node.val <= 100
算法1
(BFS层序遍历) $O(n)$
构建队列,采用BFS遍历二叉树中所有节点,
将每层节点通过next指针连接起来。
时间复杂度
时间复杂度$O(n)$:每个节点被遍历一次
空间复杂度$O(n)$:维护一个队列
Java 代码
class Solution {
public Node connect(Node root) {
if (root == null) return null;
Queue<Node> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()){
Node last = null;
int size = queue.size();
for (int i = 0; i < size; i ++){
Node p = queue.poll();
if (p.left != null)
queue.offer(p.left);
if (p.right != null)
queue.offer(p.right);
if (i != 0)
last.next = p;
last = p;
}
}
return root;
}
}
算法2
(利用.next 指针) $O(n)$
定义成员变量last、nextLine
last表示当前层遍历到的节点
nextLine表示二叉树下一层最左端的节点
对于每一层的遍历,初始化last = null,nextLine = null
时间复杂度
时间复杂度$O(n)$:每个节点被遍历一次
空间复杂度$O(1)$: 遍历时直接操作节点的next指针,无需额外空间
Java 代码
class Solution {
Node last,nextLine;
public Node connect(Node root) {
if (root == null) return null;
Node cur = root;
while (cur != null){
last = null; nextLine = null;
for (Node p = cur; p != null; p = p.next){
if (p.left != null)
solution(p.left);
if (p.right != null)
solution(p.right);
}
cur = nextLine;
}
return root;
}
public void solution(Node p){
if(last != null)
last.next = p;
if(nextLine == null)
nextLine = p;
last = p;
}
}