【面试高频题】填充二叉树节点的右侧指针| 8月更文挑战

162 阅读2分钟

微软和谷歌的几个大佬组织了一个面试刷题群,可以加管理员VX:sxxzs3998(备注掘金),进群参与讨论和直播

1.题目

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

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

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

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

进阶:

你只能使用常量级额外空间。 使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。

示例:

image.png

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

2.解析

题目说了,输入是一棵「完美二叉树」,形象地说整棵二叉树是一个正三角形,除了最右侧的节点 next 指针会指向 null,其他节点的右侧一定有相邻的节点。

二叉树的问题难点在于,如何把题目的要求细化成每个节点需要做的事情。

但是如果只依赖一个节点的话,肯定是没办法连接「跨父节点」的两个相邻节点的。

增加函数参数,一个节点做不到,我们就给他安排两个节点。

将每一层二叉树节点连接起来可以细化成将每两个相邻节点都连接起来:

class Solution {
    public Node connect(Node root) {
        if(root == null) return root;
        connectTwo(root.left, root.right);
        return root;
    }
​
    public void connectTwo(Node node1, Node node2){
        if(node1 == null || node2 == null){
            return;
        }
        node1.next = node2;
        connectTwo(node1.left, node1.right);
        connectTwo(node2.left, node2.right);
        connectTwo(node1.right, node2.left);
    }
}

这样,connectTwoNode 函数不断递归,可以无死角覆盖整棵二叉树,将所有相邻节点都连接起来,这道题就解决了。

微软和谷歌的几个大佬组织了一个面试刷题群,可以加管理员VX:sxxzs3998(备注掘金),进群参与讨论和直播