0
点赞
收藏
分享

微信扫一扫

114. 二叉树展开为链表

单调先生 2022-03-21 阅读 36
leetcode

要求:按前序拆成链表
思路:
错误示范:访问2左二子3时已经把2右儿子4改成3了,4丢了

class Solution {
public:
    TreeNode* pre;
    void preorder(TreeNode* root){
        pre->right=root;//可能还会回到pre右儿子这里不能改
        pre=root;
        if(root->left)preorder(root->left);
        if(root->right)preorder(root->right);
        root->left=nullptr;
    }
    void flatten(TreeNode* root) {
        if(!root)return;
        TreeNode* head=new TreeNode(-1);
        pre=head;
        preorder(root);
    }
};

正确示范,既然丢了就先存起来。最后rootleft可以换成在pre处就改了

class Solution {
public:
    TreeNode* pre;
    void preorder(TreeNode* root){
        pre->right=root;
        pre=root;
        TreeNode* l=root->left;
        TreeNode* r=root->right;
        if(l)preorder(l);
        if(r)preorder(r);
        root->left=nullptr;
    }
    void flatten(TreeNode* root) {
        if(!root)return;
        TreeNode* head=new TreeNode(-1);
        pre=head;
        preorder(root);
    }
};

法二:倒过来遍历不用考虑丢失的问题

class Solution {
public:
    TreeNode* pre=nullptr;
    void rpreorder(TreeNode* root){
        if(root->right)rpreorder(root->right);
        if(root->left)rpreorder(root->left);
        root->left=nullptr;
        root->right=pre;
        pre=root;
    }
    void flatten(TreeNode* root) {
        if(!root)return;
        rpreorder(root);
    }
};

法三:先序遍历迭代写法是先入栈所有左节点,然后弹出一个换右节点,循环。另一种写法是类似层序,右孩子比左孩子入栈

class Solution {
public:
    void flatten(TreeNode* root) {
        if(!root)return;
        stack<TreeNode*> s;
        TreeNode* pre=nullptr;
        s.push(root);
        while(!s.empty()){
            TreeNode* tmp=s.top();
            s.pop();
            if(pre){
                pre->right=tmp;
                pre->left=nullptr;
            }
            pre=tmp;
            if(tmp->right)s.push(tmp->right);
            if(tmp->left)s.push(tmp->left);
        }
    }
};

法四:想象。

class Solution {
public:
    void flatten(TreeNode* root) {
        while (root != nullptr) {
            if (root->left != nullptr) {
                auto most_right = root->left; // 如果左子树不为空, 那么就先找到左子树的最右节点
                while (most_right->right != nullptr) most_right = most_right->right; // 找最右节点
                most_right->right = root->right; // 然后将跟的右孩子放到最右节点的右子树上
                root->right = root->left; // 这时候跟的右孩子可以释放, 因此我令左孩子放到右孩子上
                root->left = nullptr; // 将左孩子置为空
            }
            root = root->right; // 继续下一个节点
        }
        return;
    }
};
举报

相关推荐

0 条评论