题目
给定一个二叉树,原地将它展开为一个单链表。
例如,给定二叉树
1
/
2 5
/ \
3 4 6
将其展开为:
1
\
2
\
3
\
4
\
5
\
6
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解法1:投机取巧,没有满足原地的条件
思想:前序遍历放入队列中,然后依次进行指针处理变为链表
class Solution {
public:
void preOrder(queue<TreeNode*> &v,TreeNode* root)
{
if(root==nullptr) return;
v.push(root);
preOrder(v,root->left);
preOrder(v,root->right);
}
void flatten(TreeNode* root) {
if(root==nullptr) return;
queue<TreeNode*> v;
preOrder(v,root);
TreeNode* t;
t=v.front();
v.pop();
while(!v.empty())
{
t->left=nullptr;
t->right=v.front();
t=t->right;
v.pop();
}
}
};
解法2:原地
还是分析子问题。
假设左子树处理好了,已经是直的了,我们需要什么?
-
需要左直树中最后一个节点,我们叫它为left_last
-
需要保存root的左孩子节点和右孩子节点
1
/ \
2 5
/ \ \
3 4 6
root:1
left:2
right:5
2
/ \
3 4
变为:
2
\
3
\
4(left_last)
假设右子树处理好了,已经是直的了,我们需要什么?
- 需要右直树中最后一个节点,我们叫它为right_last
5
\
6
变为:
5
\
6(right_last)
那么left_last和right_last怎么找? 其实本质是叶节点。
1(root)
left: 2-3-4(left_last)
right: 5-6(right_last)
root->left=nullptr;
root->right=left;
left_last->right=right; //所以会有这段核心代码
class Solution {
public:
void preOrder(TreeNode* root,TreeNode* &last)
{
if(root==nullptr) return;
TreeNode* left_last=0;
TreeNode* right_last=0;
TreeNode* left=root->left;
TreeNode* right=root->right;
//pre 前序需要处理的事情是找last
if(root->left==nullptr&&root->right==nullptr)
{
last=root;
return;
}
if(root->left)
{
preOrder(root->left,left_last);
//in 中序需要做的是,去处理left_last
if(left_last)
{
root->left=nullptr;
root->right=left;
left_last->right=right;
last=left_last;//如果右子树没有right_last 那么就返回left_last作为递归上层的last
}
}
if(root->right)
{
preOrder(root->right,right_last);
//post
if(right_last)
{
last=right_last;//返回right_last作为递归上层的last
}
}
}
void flatten(TreeNode* root) {
TreeNode* last=0;
preOrder(root,last);
}
};
题解3:
官方题解明天中午看看,线索树很不错