题目要求
给定一个二叉树,原地将它展开为链表。
例如,给定二叉树
1
/ \
2 5
/ \ \
3 4 6
将其展开为:
1
\
2
\
3
\
4
\
5
\
6
题解
https://github.com/soulmachine/leetcode
递归版
class Solution {
public:
void flatten(TreeNode* root) {
if(!root) return;
flatten(root->left);
flatten(root->right);
if(!root->left) return;
// 三方合并,将左子树所形成的链表插入到 root 和 root->right 之间
TreeNode *p=root->left;
while(p->right) p=p->right; //寻找左链表最后一个节点
p->right=root->right;
root->right=root->left;
root->left=nullptr;
}
};
用图表示几种主要情况吧,方便理解。
1 1
/ \ -> \
2 3 2
\
3
1 1 1
/ \ / \ \
2 5 -> 2 5 -> 2
/ \ \ \ \ \
3 4 6 3 6 3
\ \
4 4
\
5
\
6
递归2
不太好理解,看着结果能一步步分析出来,但仅看代码翻译流程还是有些抽象了。
class Solution {
public:
TreeNode* flatten(TreeNode *root,TreeNode *tail){
if(!root) return tail;
root->right=flatten(root->left,flatten(root->right,tail));
root->left=NULL;
return root;
}
void flatten(TreeNode* root) {
flatten(root,NULL);
}
};
playground结果打印
class Solution {
public:
TreeNode* flatten(TreeNode *root,TreeNode *tail){
cout<<"root "<<(root?root->val:-1)<<endl;
cout<<"tail "<<(tail?tail->val:-1)<<endl;
cout<<"@1 "<<endl;
prettyPrintTree(root);
if(!root) return tail;
root->right=flatten(root->left,flatten(root->right,tail));
root->left=NULL;
cout<<"@2 "<<endl;
prettyPrintTree(root);
return root;
}
void flatten(TreeNode* root) {
flatten(root,NULL);
}
};
输出
root 1
tail -1
@1
│ ┌── 6
│ ┌── 5
└── 1
│ ┌── 4
└── 2
└── 3
root 5
tail -1
@1
│ ┌── 6
└── 5
root 6
tail -1
@1
└── 6
root -1
tail -1
@1
Empty treeroot -1
tail -1
@1
Empty tree@2
└── 6
root -1
tail 6
@1
Empty tree@2
│ ┌── 6
└── 5
root 2
tail 5
@1
│ ┌── 4
└── 2
└── 3
root 4
tail 5
@1
└── 4
root -1
tail 5
@1
Empty treeroot -1
tail 5
@1
Empty tree@2
│ ┌── 6
│ ┌── 5
└── 4
root 3
tail 4
@1
└── 3
root -1
tail 4
@1
Empty treeroot -1
tail 4
@1
Empty tree@2
│ ┌── 6
│ ┌── 5
│ ┌── 4
└── 3
@2
│ ┌── 6
│ ┌── 5
│ ┌── 4
│ ┌── 3
└── 2
@2
│ ┌── 6
│ ┌── 5
│ ┌── 4
│ ┌── 3
│ ┌── 2
└── 1
[1, null, 2, null, 3, null, 4, null, 5, null, 6, null, null]
迭代
class Solution {
public:
void flatten(TreeNode* root) {
if(!root) return;
stack<TreeNode*> s;
s.push(root);
while(!s.empty()){
auto p=s.top();
s.pop();
if(p->right)
s.push(p->right);
if(p->left)
s.push(p->left);
p->left=nullptr;
if(!s.empty())
p->right=s.top();
}
}
};