力扣第116题-填充每个节点的下一个右侧节点指针

277 阅读3分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

前言

力扣第116题 填充每个节点的下一个右侧节点指针 如下所示:

给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:

struct Node {
  int val;
  Node *left;
  Node *right;
  Node *next;
}

填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL

初始状态下,所有 next 指针都被设置为 NULL

示例 1:

输入: root = [1,2,3,4,5,6,7]
输出: [1,#,2,3,#,4,5,6,7,#]
解释: 给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。序列化的输出按层序遍历排列,同一层节点由 next 指针连接,'#' 标志着每一层的结束。

示例 2:

输入: root = []
输出: []

一、思路

题目中有两个重要的信息需要注意以下:

  1. 二叉树为完全二叉树,即每个节点都有左右孩子(除了叶子节点)
  2. next 指向同一层的右边一个节点

知道了上面两个信息后,我们就就可以使用 递归 来实现层序遍历。并在遍历的过程中改变节点的 next 指向。

虽然知道这一题使用 递归 来实现的,但是我们还是要清除递归的具体过程。具体的过程如下图解算法所示:

图解算法

这里就使用示例一作为例子来说明

  1. 从根节点出发

image.png

  1. 将当前节点 1 的左孩子的 next 指向右孩子,2.next -> 3

image.png

  1. 处理 1 的左孩子 2,将节点 2 的左孩子的 next 指向右孩子,4.next -> 5

image.png

  1. 关键一步:再处理 2 的右孩子 5,将节点 5next 指向当前节点的 next 的左孩子,即 2.right.next -> 2.next.left

image.png

  1. 后续处理根节点右孩子的步骤同上,不过多说明

通过上面图解的方式,我们可以很清晰的看到递归的过程,写算法的过程也就很简单了。大致的步骤如下所示:

node 标识当前的节点

  1. 将左孩子指向右孩子,即 node.left.next = node.right
  2. 如果同级还有元素,即 node.next != null,将 node.right.next = node.next.left
  3. 按照上面的步骤依次处理左子树和右子树即可

二、实现

实现代码

实现代码与思路中保持一致

    public Node connect(Node root) {
        if (root == null){
            return null;
        }
        if (root.left == null){ // 叶子节点
            return root;
        }
        root.left.next = root.right;
        if (root.next != null){ // 同级还有元素
            root.right.next = root.next.left;
        }
        connect(root.left);
        connect(root.right);
        return root;
    }

测试代码

public static void main(String[] args) {
    Node node = new Node(1,
            new Node(2, new Node(4), new Node(5), null),
            new Node(3, new Node(6), new Node(7), null),
            null);
    new Number116().connect(node);
}

结果

image.png

三、总结

感谢看到最后,非常荣幸能够帮助到你~♥

如果你觉得我写的还不错的话,不妨给我点个赞吧!如有疑问,也可评论区见~