填充每个节点的下一个右侧节点指针 II --java记录

填充每个节点的下一个右侧节点指针 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;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值