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 = []
输出: []
一、思路
题目中有两个重要的信息需要注意以下:
- 二叉树为完全二叉树,即每个节点都有左右孩子(除了叶子节点)
next指向同一层的右边一个节点
知道了上面两个信息后,我们就就可以使用 递归 来实现层序遍历。并在遍历的过程中改变节点的 next 指向。
虽然知道这一题使用 递归 来实现的,但是我们还是要清除递归的具体过程。具体的过程如下图解算法所示:
图解算法
这里就使用示例一作为例子来说明
- 从根节点出发
- 将当前节点
1的左孩子的next指向右孩子,2.next -> 3
- 处理
1的左孩子2,将节点2的左孩子的next指向右孩子,4.next -> 5
- 关键一步:再处理
2的右孩子5,将节点5的next指向当前节点的next的左孩子,即2.right.next -> 2.next.left
- 后续处理根节点右孩子的步骤同上,不过多说明
通过上面图解的方式,我们可以很清晰的看到递归的过程,写算法的过程也就很简单了。大致的步骤如下所示:
node 标识当前的节点
- 将左孩子指向右孩子,即
node.left.next = node.right - 如果同级还有元素,即
node.next != null,将node.right.next = node.next.left - 按照上面的步骤依次处理左子树和右子树即可
二、实现
实现代码
实现代码与思路中保持一致
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);
}
结果
三、总结
感谢看到最后,非常荣幸能够帮助到你~♥
如果你觉得我写的还不错的话,不妨给我点个赞吧!如有疑问,也可评论区见~