LeetCode 116:填充每个节点的下一个右侧节点指针
题目描述
给定一个完美二叉树,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。
初始状态下,所有 next 指针都被设置为 NULL。
【示例】
【提示】
- 你只能使用常量级额外空间。
- 使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。
【难度】
中等
解题
因为是完美二叉树,所以不需要考虑许多结构上的可能性,只需要连接即可。对于一个节点,连接其左子节点与右子节点很简单,需要思索的是跨子树间的连接,我想到的是借助当前树已经建立的连接关系,即当前树的右子树与当前树下一个节点的左子树连接。那需要做好:
- 连接左子节点与右节点。
- 建立当前结点右子节点与当后一节点左子节点的连接,若不存在后一节点,则右子节点的后一节点为空。
- 最重要的是在建立当前节点子节点的关系之前,建立当前节点的前后连接。
- 连接时从左指向右的,因此遍历顺序应先左后右。
以下是代码:
递归
/*
// Definition for a Node.
class Node {
public:
int val;
Node* left;
Node* right;
Node* next;
Node() : val(0), left(NULL), right(NULL), next(NULL) {}
Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}
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 || root->left==NULL)
return root;
root->left->next = root->right; //建立左右子节点的连接
root->right->next = root->next ? root->next->left : NULL; //建立右子节点与后节点左子节点的连接
connect(root->left); //遍历先左
connect(root->right);
return root;
}
};
迭代
迭代方法与递归方法本质时一样的,区别在于遍历树的过程是由上到下由左到右的方式,过程依赖于循环,有点像遍历整个图像数据的过程。
/*
/*
// Definition for a Node.
class Node {
public:
int val;
Node* left;
Node* right;
Node* next;
Node() : val(0), left(NULL), right(NULL), next(NULL) {}
Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}
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 root;
Node *cur_node = root, *cur_left = root->left;
//外层由上到下
while (cur_left){
//内层由左到右
while (cur_node){
cur_node->left->next = cur_node->right;
cur_node->right->next = cur_node->next ? cur_node->next->left : NULL;
cur_node = cur_node->next;
}
cur_node = cur_left;
cur_left = cur_node->left;
}
return root;
}
};