日拱一卒——LeetCode116.填充每个节点的下一个右侧节点指针

大家好呀,今天为大家带来的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

猜你喜欢

转载自blog.csdn.net/issunmingzhi/article/details/109092466