题目来源
题目描述
struct Node{
int val;
Node *left;
Node *right;
Node *next;
};
class Solution {
public:
Node* connect(Node* root) {
}
};
题目解析
递归
class Solution {
public:
Node* connect(Node* root) {
if(root == nullptr){
return nullptr;
}
Node *left = root->left;
Node *right = root->right;
while (left != nullptr){
left->next = right;
left = left->right;
right = right->left;
}
connect(root->left);
connect(root->right);
return root;
}
};
递归
- 每个node左子树的next,就是node的右子树
- 每个node右子树的next。就是node.next的左子树
class Solution {
void process(Node* node, Node *next){
if(node != nullptr){
node->next = next;
process(node->left, node->right);
process(node->right, node->next != nullptr ? node->next->left : nullptr);
}
}
public:
Node* connect(Node* root) {
helper(root, null);
return root;
}
};
递归写法
由于是完全二叉树:
- 所以若节点的左子结点存在的话,其右子节点必定存在,所以左子结点的 next 指针可以直接指向其右子节点
- 对于其右子节点的处理方法是,判断其父节点的 next 是否为空,若不为空,则指向其 next 指针指向的节点的左子结点,若为空则指向 NULL
class Solution {
public:
Node* connect(Node* root) {
if(!root){
return NULL;
}
if(root->left){
root->left->next = root->right;
}
if(root->right){
root->right->next = root->next ? root->next->left : NULL;
}
connect(root->left);
connect(root->right);
return root;
}
};
两个指针
用两个指针start个cur,其中start标记每一层的起始节点,cur用来遍历该层的节点
class Solution {
public:
Node* connect(Node* root) {
if (!root) return NULL;
Node *start = root, *cur = NULL;
while (start->left) {
cur = start;
while (cur) {
cur->left->next = cur->right;
if (cur->next) cur->right->next = cur->next->left;
cur = cur->next;
}
start = start->left;
}
return root;
}
};
队列
由于是层序遍历,每层的节点都按顺序加入 queue 中,而每当从 queue 中取出一个元素时,将其 next 指针指向 queue 中下一个节点即可,对于每层的开头元素开始遍历之前,先统计一下该层的总个数,用个 for 循环,这样当 for 循环结束的时候,该层就已经被遍历完了
class Solution {
public:
Node* connect(Node* root) {
if(root == NULL){
return NULL;
}
std::queue<Node *> st;
st.push(root);
while (!st.empty()){
int len = st.size();
for (int i = st.size(); i > 0; --i) {
Node *t = st.front(); st.pop();
if(i != 1){
t->next = st.front();
}
if(t->left){
st.push(t->left);
}
if(t->right){
st.push(t->right);
}
}
}
return root;
}
};
类似题目
题目 | 思路 |
---|---|
leetcode:116. 完全二叉树填充每个节点的下一个右侧节点指针 Populating Next Right Pointers in Each Node | |
leetcode:117. 普通二叉树填充每个节点的下一个右侧节点指针 Populating Next Right Pointers in Each Node II | |
leetcode:199. 二叉树的右视图 Binary Tree Right Side View | 我们对树进行深度优先搜索,在搜索过程中,我们总是先访问右子树。那么对于每一层来说,我们在这层见到的第一个结点一定是最右边的结点;使用层序遍历,并只保留每层最后一个节点的值 |