题目
给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:
struct Node { int val; Node *left; Node *right; Node *next; } 填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。
初始状态下,所有 next 指针都被设置为 NULL。
进阶:
你只能使用常量级额外空间。 使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。
示例: 输入:root = [1,2,3,4,5,6,7] 输出:[1,#,2,3,#,4,5,6,7,#] 解释:给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。序列化的输出按层序遍历排列,同一层节点由 next 指针连接,’#’ 标志着每一层的结束。
class Solution {
public:
Node* connect(Node* root) {
if(root==NULL) return root;
Node *leftmost = root;
while(leftmost->left!=NULL){
Node *head = leftmost;
while(head!=NULL){
head->left->next = head->right;
if(head->next!=NULL)
head->right->next = head->next->left;
head = head->next;
}
leftmost = leftmost->left;
}
return root;
}
};
-
时间复杂度O(n) -
空间复杂度O(1) -
思路
- 层序遍历,使用已经建立的上层的next指针,为该层的节点设置next指针。
- 设置leftmost作为遍历每一层的时每一层的起点,第一层不需要设置next指针,从第二层开始的每一层借助上一层的next指针设置该层的指针
- 第一种情况是连接同一个父节点的两个子节点,左孩子的next指针指向右孩子
- 第二种情况是二者没有共同的父亲节点,右孩子的next指针指向其父亲节点next指针所指的节点的左孩子
-
方法二:递归
class Solution {
public:
Node* connect(Node* root) {
if(root==NULL) return root;
if(root->left==NULL) return root;
root->left->next = root->right;
if(root->next) root->right->next = root->next->left;
connect(root->left);
connect(root->right);
return root;
}
};
-
时间复杂度O(n) -
空间复杂度O(logn) -
思路
- 对每一个节点,填充它左右孩子的next指针,再对它的左右孩子进行递归调用,向下深入。
-
方法三:递归二
class Solution {
public:
Node* connect(Node* root) {
if(root==NULL) return root;
Node *left = root->left;
Node *right = root->right;
while(left!=NULL){
left->next = right;
left = left->right;
right = right->left;
}
connect(root->left);
connect(root->right);
return root;
}
};
- 时间复杂度O(n)
- 空间复杂度O(logn)
- 思路
- 对每一个节点root,它的左孩子不断向右走,右孩子不断向左走,二者在同一层中始终是相邻的,即left->next=right,直到left为空
- 再分别递归调用root的左右孩子为根,不断向下深入。
方法三参考详解
|