算法初探LeetCode-填充每个节点的下一个右侧节点指针II

110 阅读2分钟

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

给定一个二叉树:

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

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

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

示例 1:

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

示例 2:

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

提示:

  • 树中的节点数在范围 [0, 6000] 内
  • -100 <= Node.val <= 100

思路分析

自顶向上递归构建next,分为以下几步:

构建当前节点的左节点:

1.1. 如果root有左节点和右节点,则左节点的Next为右节点

1.2. 如果root右节点为Null,则查找父节点的兄弟节点的最左边子元素

构建当前节点的右节点:

2.1. 如果root右节点不为Null,则next为父节点的兄弟节点的最左边子元素

递归:这里注意一定要先构建右子树,再构建左子树,因为寻找父节点的兄弟节点是从左到右遍历的,如果右子树未构建好就遍历,则会出错

算法代码

public Node connect(Node root) {
    //自顶向上递归
    if (root == null) return null;

    //构建当前节点的左节点
    if (root.left != null) {
        //1.如果root有左节点和右节点,则左节点的Next为右节点
        if (root.right != null) root.left.next = root.right;
        //2.如果root右节点为Null,则查找父节点的兄弟节点的最左边子元素
        else root.left.next = findLeftChild(root);
    }

    //构建当前节点的右节点
    if (root.right != null)
    //如果root右节点不为Null,则next为父节点的兄弟节点的最左边子元素
        root.right.next = findLeftChild(root);

    //递归
    connect(root.right);
    connect(root.left);

    return root;
}

private Node findLeftChild(Node root) {
    if (root.next == null) return null;
    while (root.next != null) {
        if (root.next.left != null) return root.next.left;
        if (root.next.right != null) return root.next.right;
        root = root.next;
    }
    return null;
}

结果详情

Snipaste_2023-06-06_23-03-54.png

算法复杂度

  • 空间复杂度:O(1)O(1)
  • 时间复杂度:O(n)O(n)

掘金(JUEJIN)一起进步,一起成长!