填充每个节点的下一个右侧节点指针 II
使用递归
这套题和填充每个节点的下一个右侧节点指针1递归写法有一点点区别。
递归时需要先构建右子树。与1不同时因为在构建按root的孩子节点next指向时,可能会需要指向root.next.next 以后的孩子,而若先递归左子树则只能找到root.next的孩子,后面就无法找到导致构建next失败。
class Solution {
public Node connect(Node root) {
if(root == null) return null;
if(root.left != null){
if(root.right != null){
root.left.next = root.right;
}else{
root.left.next = findNode(root.next);
}
}
if(root.right != null){
root.right.next = findNode(root.next);
}
connect(root.right);//需要先构建右子树
connect(root.left);
return root;
}
public Node findNode(Node root){ //找root节点以及root右侧兄弟节点 中出现的第一个孩子节点,直至root不存在。
if (root == null) return null;
while(root != null){
if(root.left != null) return root.left;
if(root.right != null) return root.right;
root = root.next;
}
return root;
}
}
使用栈进行层次遍历
和填充每个节点的下一个右侧节点指针1的栈使用方法类似,只是next指向时需要查找节点。
class Solution {
public Node connect(Node root) {
if(root == null) return null;
Queue<Node> queue = new LinkedList<Node>();
root.next = null;
queue.offer(root);
while(!queue.isEmpty()){
int size = queue.size();//队列里面保存为一层的节点数。
while(size > 0){
// 将这一层孩子节点连接
Node temp = queue.poll();
if(temp.left != null){
if(temp.right != null){
temp.left.next = temp.right;
}else{
temp.left.next = findNode(temp.next);
}
queue.offer(temp.left);
}
if(temp.right != null){
temp.right.next = findNode(temp.next);
queue.offer(temp.right);
}
size --;
}
}
return root;
}
public Node findNode(Node root){ //找root节点以及root右侧兄弟节点 中出现的第一个孩子节点,直至root不存在。
if (root == null) return null;
while(root != null){
if(root.left != null) return root.left;
if(root.right != null) return root.right;
root = root.next;
}
return root;
}
}
方法不用使用栈,进行层次遍历。
思路:不用栈记录需要访问节点,那么需要用一个first节点记录一层遍历起始位置,然后利用firt.next 可以遍历本层所有节点,进行孩子节点连接操作。
例如:
root节点
1、cur = root
2、遍历cur 节点层,如果cur.left存在则设置 first = cur.left,不存在 cur.right 存在first = cur.right,都不存在则继续找cur.next的孩子节点(记录下一层第一个节点)
3、在找第一个到第一个节点时,该进行连接操作了,node = first ,相继遍历此层将所有node节点(cur层的孩子节点)连接。
4、本层循环完后,将cur 指向 first节点,则对孩子层进行遍历。并将fist = null,以便继续更新下一层第一个位子
class Solution {
public Node connect(Node root) {
if(root == null) return null;
Node curNode = root;
root.next = null;
Node first = null; //记录root 孩子层次的头节点。
Node node = null; //做链接节点
while(curNode != null){
while(curNode != null){//层循环,将本层孩子节点全部链接
if(curNode.left != null){
if(first == null){ //记录head 节点,与将要链接的node
first = curNode.left;
node = first;
}else{ //做链接
node.next = curNode.left;
node = node.next;
}
}
if(curNode.right != null){
if(first == null){
first = curNode.right;
node = first;
}else{
node.next = curNode.right;
node = node.next;
}
}
curNode = curNode.next;
}
//一层链接完毕,最后一个节点next还没有置空,不加程序也不会报错。
if(node != null) {
node.next = null;
}
curNode = first; //进行下一次链接
first = null; //
}
return root;
}
}