此题最naive的办法就是利用队列进行BFS,同一层的节点从左到右连接起来即可。但这样一来需要的额外空间至少是树的最大宽度。
下面的解法需要的额外空间是树的高度,相比于树的宽度,树的高度一般情况来说不会太大,为logN级别。基本思路是维护每一层的第一个尚未连接起来的节点,当该层的一下个节点到来时,将其与新的节点连接起来,并替换为新的节点。
/**
* Definition for binary tree with next pointer.
* struct TreeLinkNode {
* int val;
* TreeLinkNode *left, *right, *next;
* TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {}
* };
*/
class Solution {
public:
vector<TreeLinkNode*> nodeLevels;
void dfs(int depth,TreeLinkNode* root)
{
if(root==NULL)
{
return;
}
if(nodeLevels.size()<=depth)
{
nodeLevels.push_back(root);
}
else
{
nodeLevels[depth]->next=root;
nodeLevels[depth]=root;
}
dfs(depth+1,root->left);
dfs(depth+1,root->right);
}
void connect(TreeLinkNode *root) {
dfs(0,root);
}
};
接下来是参考网上的一个解法,只需要常数级别的额外空间。这个解法本质上是一层一层扫描,关键在于“在当前层上考虑连接下一层”,这样每次进入新的一层时,该层已经被next指针连接好了。
要注意利用上next指针,我就是没有想到利用next指针,所以没有找到常数级额外空间的解法
/**
* Definition for binary tree with next pointer.
* struct TreeLinkNode {
* int val;
* TreeLinkNode *left, *right, *next;
* TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {}
* };
*/
class Solution {
public:
void connect(TreeLinkNode *root) {
TreeLinkNode* head=NULL;
TreeLinkNode* prev=NULL;
TreeLinkNode* cur=root;
while(cur!=NULL)
{
while(cur!=NULL)
{
if(cur->left!=NULL)
{
if(prev!=NULL)
{
prev->next=cur->left;
}
else
{
head=cur->left;
}
prev=cur->left;
}
if(cur->right!=NULL)
{
if(prev!=NULL)
{
prev->next=cur->right;
}
else
{
head=cur->right;
}
prev=cur->right;
}
cur=cur->next;
}
cur=head;
head=NULL;
prev=NULL;
}
}
};