填充每个节点的下一个右侧节点指针 II

133 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第18天,点击查看活动详情

一、题目

leetcode 填充每个节点的下一个右侧节点指针 II

给定一个二叉树

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

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

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

示例:

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

提示:

树中的节点数小于 6000
-100 <= node.val <= 100

二、题解 简单来说就是需要将一个二叉树的每一层节点从左到右连接成一个单链表,给定二叉树不一定为满二叉树。

方法一 因为是要连接每一层的节点成为一个链表,那么我们可以获取到每一层的节点,然后按从左到右的顺序连接成一个单链表就行了,因为二叉树不一定是满二叉树,所以我们需要将上一个节点的next连接到当前节点。那么要获取二叉树每一层的节点,我们可以通过层序遍历这个二叉树获得。所以我们需要对二叉树就行层序遍历,使用一个队列辅助我们遍历二叉树,具体的先将二叉树的根节点加入队列queue,然后循环取出队列元素(每次循环我们都要取出当前层所以元素节点),所以先用size记录当前队列元素大小,代表当前层的元素节点数量,并且还需要一个pre指针,代表当前层的前一个不为空的元素节点,方便我们将上一个节点连接到当前节点。然后我们就依次取出这些元素节点,如果取出的元素节点node为空就跳过,否则就将上一个节点pre连接上当前节点(如果存在的话),然后将pre节点更新为当前节点,最后将当前节点的子树添加到队列中继续遍历。

三、代码

方法一 Java代码

class Solution {
    public Node connect(Node root) {
        if (root == null) {
            return null;
        }
        Queue<Node> queue = new LinkedList<Node>();
        queue.add(root);
        while (!queue.isEmpty()) {
            int size = queue.size();
            Node pre = null;
            for (int i = 0; i < size; i++) {
                Node node = queue.poll();
                if (node == null) {
                    continue;
                }
                if (i > 0 && pre != null) {
                    pre.next = node;
                }
                pre = node;
                queue.offer(node.left);
                queue.offer(node.right);
            }
        }
        return root;
    }
}

时间复杂度:O(n),需要层序遍历一次二叉树的所有节点。

空间复杂度:O(n),需要一个队列空间辅助二叉树的层序遍历。