当前位置 博文首页 > 冢狐的私人空间:日拱一卒——LeetCode116.填充每个节点的下一个

    冢狐的私人空间:日拱一卒——LeetCode116.填充每个节点的下一个

    作者:[db:作者] 时间:2021-08-14 18:10

    大家好呀,今天为大家带来的LeetCode的题目是:LeetCode116.填充每个节点的下一个右侧节点指针。属于一道关于二叉树的中等难度的题目。

    题目

    image

    分析

    看完题目后看一下提示内容,一个是只能使用常量级的额外空间,一个是可以使用递归的方法来解决该题目。要是不通过提示的话,看完这个题目的第一反应的解法就是层次遍历,题目要求的是每一层都建立指针,那么我们只需要逐层遍历即可。

    通过提示我们知道还有第二种解法就是递归方法。

    解法一:层次遍历

    这种是最直观的,也是思维难度较低的一种算法,就是从根节点逐层遍历,在遍历的过程中建立指针。

    层次遍历是基于广度优先搜索的,与广度优先搜索不同的是,广度优先搜索每次只会取出一个节点,而层次遍历还会把该层元素都获取到,这样我们就可以实现在遍历中修改每个节点的next指针,同时也将其子节点加入到队列中

    解法二:递归

    对于要建立指针的两个节点来说,只有两种情况:

    • 第一种:这两个节点属于同一个父节点,这样我们只需要:node.left.next=node.right
    • 第二种:这两个节点属于不同的父节点,这种情况下无法直接连接,所以我们需要从上往下进行建立,利用本层以及建立好的指针来为下一层建立连接。

    具体做法就是,从根节点开始遍历(根节点不需要建立连接),然后根据这层的连接关系,开始为下一层建立连接,首先先建立第一种情况的连接,然后利用该层的连接针对第二种情况进行建立连接。

    需要注意的是当我们为第N层节点建立next指针时,处于第N-1层。当第N层节点的next指针全部建立完成后,移至第N层,开始建立第N+1层节点的next指针。

    代码实现

    解法一:层次遍历

    public Node connect(Node root) {
            if (root == null) {
                return root;
            }
            // 初始化队列同时将第一层节点加入队列中,即根节点
            Queue<Node> queue = new LinkedList<Node>();
            queue.add(root);
            // 外层的 while 循环迭代的是层数
            while (!queue.isEmpty()) {
                // 记录当前队列大小
                int size = queue.size();
                // 遍历这一层的所有节点
                for (int i = 0; i < size; i++) {
                    // 从队首取出元素(移除)
                    Node node = queue.poll();
                    // 连接,注意最后一个不需要进行连接,所以要有一个判断。
                    if (i == size - 1) {
                        node.next = queue.peek();
                    }
                    // 将下一层的节点放进去
                    if (node.left != null) {
                        queue.add(node.left);
                    }
                    if (node.right != null) {
                        queue.add(node.right);
                    }
                }
            }
            // 返回根节点
            return root;
        }
    }
    

    解法二:

    public Node connect(Node root) {
            if (root == null) {
                return root;
            }
            // 从根节点开始
            Node leftmost = root;
            while (leftmost.left != null) {
                // 遍历这一层节点组织成的链表,为下一层的节点更新 next 指针
                Node head = leftmost;
                while (head != null) {
                    // 第一种情况,两个需要建立的子节点有共同的父节点
                    head.left.next = head.right;
                    // 第二种情况,此时需要借助上一层的指针来进行建立
                    if (head.next != null) {
                        head.right.next = head.next.left;
                    }
                    // 指针向后移动,即从该层开始往右边进行移动
                    head = head.next;
                }
                // 去下一层的最左的节点,由于建立了该层的连接所以只需要从最左节点开始遍历即可
                leftmost = leftmost.left;
            }
            return root;
        }
    

    最后

    • 如果觉得看完有收获,希望能给我点个赞,这将会是我更新的最大动力,感谢各位的支持
    • 欢迎各位关注我的公众号【java冢狐】,专注于java和计算机基础知识,保证让你看完有所收获,不信你打我
    • 如果看完有不同的意见或者建议,欢迎多多评论一起交流。感谢各位的支持以及厚爱。

    image

    cs
    下一篇:没有了