给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next
指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next
指针设置为 NULL
。
初始状态下,所有 next
指针都被设置为 NULL
。
进阶:
- 你只能使用常量级额外空间。
- 使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。
示例:
输入:root = [1,2,3,4,5,6,7]
输出:[1,#,2,3,#,4,5,6,7,#]
解释:给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。序列化的输出按层序遍历排列,同一层节点由 next 指针连接,'#' 标志着每一层的结束。
提示:
- 树中节点的数量少于
4096
- -1000 <=
node.val
<= 1000
思路
我的思路还是比较常规的,就是用BFS对二叉树进行层序遍历,然后遍历的时候要设置一个pre
结点代表当前结点的前驱。主要有以下两种情况:
- 如果当前结点的层次和
pre
结点的层次不一样,说明当前结点是新一层的第一个结点,因此,只要把pre
结点的next
设为null
,并将当前结点作为pre
即可; - 如果当前结点的层次和
pre
结点的层次一样,说明当前结点和pre
结点是同一层的,因此,只要把pre
结点的next
设为当前结点,然后再将当前结点作为pre
即可。
这样的话,做完一次BFS,所有结点也就处理完了。
另外,因为题目定义的二叉树结点同样没有附带层次信息,我这里自己定义了一个NodeWithLayer
类来处理,这样的话,队列里直接放NodeWithLayer
类的元素,处理起来也比较方便,代码的可读性也高。
【注】突然发现,我的代码在117. 填充每个节点的下一个右侧节点指针 II也能AC,看来这题有优化空间(这题是一个完全二叉树,而117是一个普通二叉树),但是暂时想不到,想到之后再说叭(逃)。
代码
public class Solution {
class Node {
public int val;
public Node left;
public Node right;
public Node next;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, Node _left, Node _right, Node _next) {
val = _val;
left = _left;
right = _right;
next = _next;
}
};
class NodeWithLayer{
Node node;
int layer;
NodeWithLayer() {}
NodeWithLayer(Node node, int layer){
this.node = node;
this.layer = layer;
}
}
Queue<NodeWithLayer> queue = new LinkedList<NodeWithLayer>();
public void bfs(NodeWithLayer root) {
queue.offer(root);
NodeWithLayer pre = new NodeWithLayer();
pre = root;
while(queue.isEmpty()==false) {
NodeWithLayer topNode = queue.poll();
if(topNode.layer==1) {//如果是根结点
topNode.node.next=null;
}
else {//如果不是根结点
if(topNode.layer!=pre.layer) {//如果是下一层的第一个结点
pre.node.next = null;//先将上一层的最后一个结点指向null
}
else {//如果是同一层的后一个结点
pre.node.next = topNode.node;
}
pre = topNode;//再将当前结点赋为pre,以供下次使用
}
if(topNode.node.left!=null) {
NodeWithLayer lchild = new NodeWithLayer(topNode.node.left, topNode.layer+1);
queue.offer(lchild);
}
if(topNode.node.right!=null) {
NodeWithLayer rchild = new NodeWithLayer(topNode.node.right, topNode.layer+1);
queue.offer(rchild);
}
}
}
public Node connect(Node root) {
if(root!=null) {
NodeWithLayer rootNode = new NodeWithLayer(root, 1);
bfs(rootNode);
}
return root;
}
}