「这是我参与11月更文挑战的第12天,活动详情查看:2021最后一次更文挑战」
题目描述
给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:
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 指针连接,'#' 标志着每一层的结束。 来源:力扣(LeetCode)
- 进阶:
- 你只能使用常量级额外空间。
- 使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。
题目分析
这题研究了好久,没看懂题目要表达啥,最后终于在小伙伴们的思路下才懂,算法真的令人头秃,但是刷起来还是蛮有意思的。
本题的思路如下:
- 因为每个节点包含左节点left,右节点right索引,可以直接将左节点left的next指向right,即可完成连接,这样就可以完成2和3、4和5、6和7进行两两连接;;
- 对于不是相同子节点的,我们应该怎么连接呢,比如子节点5和子节点,我们可以通过节点2的right和节点3的left进行连接;
- 递归上述步骤,直至出现子节点是null停止遍历。
时间复杂度:复杂度O(n),n为二叉树节点的个数。
空间复杂度:O(m),m为二叉树的高度。
/*
// Definition for a Node.
class Node {
public int val;
public Node left;
public Node right;
public Node next;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, Node _left, Node _right, Node _next) {
val = _val;
left = _left;
right = _right;
next = _next;
}
};
*/
class Solution {
public Node connect(Node root) {
if(root == null) return null;
//获取根节点的左右子节点
Node left = root.left;
Node right = root.right;
//递归连接其他子节点
connectTwoNode(left,right);
return root;
}
//定义递归函数,给定两个节点将它们相连
public void connectTwoNode(Node node1,Node node2){
//出现空节点直接返回
if(node1 == null || node2 == null){
return;
}
//将当前两个节点关联(如2/3)
node1.next = node2;
//将相同父节点的节点相连(如4/5,6/7)
connectTwoNode(node1.left,node1.right);
connectTwoNode(node2.left,node2.right);
//将父节点不同的子节点相连(如5、6)
connectTwoNode(node1.right,node2.left);
}
}
复制代码
官网也提供了空间复杂度更少的解法,这里直接贴出来大家研究一下:
class Solution {
public Node connect(Node root) {
if (root == null) {
return root;
}
// 从根节点开始
Node leftmost = root;
while (leftmost.left != null) {
// 遍历这一层节点组织成的链表,为下一层的节点更新 next 指针
Node head = leftmost;
while (head != null) {
// CONNECTION 1
head.left.next = head.right;
// CONNECTION 2
if (head.next != null) {
head.right.next = head.next.left;
}
// 指针向后移动
head = head.next;
}
// 去下一层的最左的节点
leftmost = leftmost.left;
}
return root;
}
}
复制代码