思路一:使用额外的数组,前向递归数组记录树的节点。然后再将左节点置nullptr,右节点依次更新。
class Solution {
public:
vector<int> v;
void flatten(TreeNode* root) {
if(!root) return;
preorder(root);
TreeNode* pre = root;
root->left = nullptr;
root->right = nullptr;
for(int i = 1; i < v.size(); i++){
TreeNode* p = new TreeNode(v[i]);
pre->right = p;
pre = p;
}
}
void preorder(TreeNode* root){
if(!root) return;
v.push_back(root->val);
preorder(root->left);
preorder(root->right);
}
};
思路二:利用前驱节点:
树展开为链表实质是找到左子树的最右节点,然后将右子树接过去。最后实现左子树全部变成空。
class Solution {
public:
vector<int> v;
void flatten(TreeNode* root) {
TreeNode* cur=root;
while(cur!=nullptr)
{
if(cur->left!=nullptr)
{
auto next=cur->left;
auto temp=next;
while(temp->right!=nullptr)
{temp=temp->right; }//找到左子树的最右节点
temp->right=cur->right; //把当前节点的右子树接在左子树的最右一个点的下面
cur->left=nullptr; //当前节点的左子树设置成nullptr
cur->right=next; //将左子树挪到当前节点的右子树上
}
cur=cur->right;
}
}
};