- 方法一
这道题希望我们把二叉树各个层的点组织成链表,一个非常直观的思路是层次遍历。
算法如下:初始化一个队列 q,将根结点放入队列中。当队列不为空的时候,记录当前队列大小为 size,即当前层的节点数,从队列中以此取出 size个元素并通过这些元素拓展新节点。如此循环,直到队列为空。
代码如下:
/*
// 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) {
queue<Node*> q;
q.push(root);
int size;
Node* node;
while (q.size()) {
for (size = q.size(); size > 0; --size) {
node = q.front();
q.pop();
if (1 == size) {
node->next = nullptr;
} else {
node->next = q.front();
}
if (node->left) {
q.push(node->left);
}
if (node->right) {
q.push(node->right);
}
}
}
}
return root;
}
};
结果:
- 方法二
在方法一中,因为对树的结构一无所知,所以使用队列保证有序访问同一层的所有节点,并建立它们之间的连接。
然而不难发现:一旦在某层的节点之间建立了 next 指针,那这层节点实际上形成了一个链表。因此,如果先去建立某一层的 next 指针,再去遍历这一层时,就无需再使用队列了。
基于该想法,提出降低空间复杂度的思路:如果第 i 层节点之间已经建立 next 指针,就可以通过 next 指针访问该层的所有节点,同时对于每个第 i 层的节点,我们又可以通过它的 left 和 right 指针知道其第 i+1 层的孩子节点是什么,所以遍历过程中就能够按顺序为第 i + 1 层节点建立 next 指针。
代码如下。
/*
// 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:
void handle(Node* &last, Node* &p, Node* &nextStart) {
if (last) {
last->next = p;
}
if (!nextStart) {
nextStart = p;
}
last = p;
}
Node* connect(Node* root) {
if (!root) {
return nullptr;
}
Node *start = root;
while (start) {
Node *last = nullptr, *nextStart = nullptr;
for (Node *p = start; p != nullptr; p = p->next) {
if (p->left) {
handle(last, p->left, nextStart);
}
if (p->right) {
handle(last, p->right, nextStart);
}
}
start = nextStart;
}
return root;
}
};
结果: