Medium
题目描述
给定一个二叉树:
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
进阶:
- 你只能使用常量级额外空间。
- 使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。
解题思路
解题思路
本题是经典的树层次连接问题。与第116题不同的是,这里的二叉树不一定是完美二叉树,因此需要处理更复杂的情况。
方法一:层序遍历(BFS)
使用队列进行层序遍历,对每一层的节点从左到右连接next指针。这是最直观的解法,但需要O(n)的额外空间。
方法二:利用已建立的连接(推荐)
这是O(1)空间复杂度的解法。核心思想是利用上一层已经建立好的next连接来遍历当前层,同时建立下一层的连接。
算法步骤:
- 从根节点开始,逐层处理
- 对于每一层,使用一个指针遍历该层的所有节点(通过next指针)
- 在遍历过程中,将下一层的节点用next指针连接起来
- 使用dummy节点技巧简化下一层连接的处理
关键点是维护当前层的遍历指针和下一层的连接指针,通过已有的next连接遍历当前层,同时构建下一层的连接关系。
代码实现
class Solution {
public:
Node* connect(Node* root) {
if (!root) return root;
Node* levelStart = root;
while (levelStart) {
Node* dummy = new Node(0);
Node* prev = dummy;
Node* curr = levelStart;
// 遍历当前层,连接下一层
while (curr) {
if (curr->left) {
prev->next = curr->left;
prev = prev->next;
}
if (curr->right) {
prev->next = curr->right;
prev = prev->next;
}
curr = curr->next;
}
levelStart = dummy->next;
delete dummy;
}
return root;
}
};
class Solution:
def connect(self, root: 'Node') -> 'Node':
if not root:
return root
level_start = root
while level_start:
dummy = Node(0)
prev = dummy
curr = level_start
# 遍历当前层,连接下一层
while curr:
if curr.left:
prev.next = curr.left
prev = prev.next
if curr.right:
prev.next = curr.right
prev = prev.next
curr = curr.next
level_start = dummy.next
return root
public class Solution {
public Node Connect(Node root) {
if (root == null) return root;
Node levelStart = root;
while (levelStart != null) {
Node dummy = new Node(0);
Node prev = dummy;
Node curr = levelStart;
// 遍历当前层,连接下一层
while (curr != null) {
if (curr.left != null) {
prev.next = curr.left;
prev = prev.next;
}
if (curr.right != null) {
prev.next = curr.right;
prev = prev.next;
}
curr = curr.next;
}
levelStart = dummy.next;
}
return root;
}
}
var connect = function(root) {
if (!root) return root;
let levelStart = root;
while (levelStart) {
let dummy = new _Node(0);
let prev = dummy;
let curr = levelStart;
// 遍历当前层,连接下一层
while (curr) {
if (curr.left) {
prev.next = curr.left;
prev = prev.next;
}
if (curr.right) {
prev.next = curr.right;
prev = prev.next;
}
curr = curr.next;
}
levelStart = dummy.next;
}
return root;
};
复杂度分析
| 复杂度类型 | 值 | 说明 |
|---|---|---|
| 时间复杂度 | O(n) | 每个节点访问一次 |
| 空间复杂度 | O(1) | 只使用常量级额外空间 |