给定一个二叉树
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。
初始状态下,所有 next 指针都被设置为 NULL。
进阶:
- 你只能使用常量级额外空间。
- 使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。
来源:力扣(LeetCode)
第一种方法,类似102题,采用层次遍历的方法,
class Solution {
public Node connect(Node root) {
if(root==null){
return root;
}
Queue<Node> queue=new LinkedList<>();
queue.add(root);
while(!queue.isEmpty()){
int size=queue.size();
Node last=null;
for(int i=0;i<size;i++){
Node node=queue.poll();
if(node.left!=null)
queue.add(node.left);
if(node.right!=null)
queue.add(node.right);
if(i!=0)
last.next=node;
last=node;
}
}
return root;
}
}
第二种方法,不使用额外的队列空间。
这是因为一旦在某层的节点之间建立了next指针,那这层节点实际上形成了一个链表,就可以通过next指针访问该层的所有节点。同时又可以通过left和right指针来访问下一层的节点,无需再使用额外的空间了。
代码如下:
class Solution {
Node last = null, nextStart = null;
public Node connect(Node root) {
if(root==null)
return null;
Node start=root;//从start开始遍历
while(start!=null){
//每次重新遍历一层时都初始化last和nextStart
last=null;
nextStart=null;
//开始顺着next指针层次遍历
for(Node p=start;p!=null;p=p.next){
if(p.left!=null)
handle(p.left);
if(p.right!=null)
handle(p.right);
}
//这一层遍历完了,开始遍历下一层
start=nextStart;
}
return root;
}
public void handle(Node p){
//last代表上一个遍历的节点,现在遍历的节点赋给上一个的next
if(last!=null)
last.next=p;
//下一层第一个遍历到的是nextStart
if(nextStart==null)
nextStart=p;
//遍历过了p,p成为了上一个遍历的节点,赋给last
last=p;
}
}