二叉树4-二叉树展开为链表、对称二叉树、合并两个有序链表、构造二

2021-04-06  本文已影响0人  rensgf

14. 二叉树展开为链表

思路:递归,将子树展开为链表。根节点右节点为左节点,左节点的右节点为右节点,左节点设为空。
错误代码:

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

错误原因:
递归不会写,思路不清晰。
正确代码:

class Solution {
public:
    void flatten(TreeNode* root) {
        if(!root)
            return;
//将根节点的左子树变成链表
        flatten(root->left);
 //将根节点的右子树变成链表
        flatten(root->right);
        TreeNode* t=root->right;
//把树的右边换成左边的链表
        root->right=root->left;
//把树的左边置空
        root->left=nullptr;
//把右边链表接到最右边
        while(root->right)
            root=root->right;
        root->right=t;
    }
};

递归表达式要放到哪里呀

101. 对称二叉树

思路是:如果镜像对称,那么遍历中-左-右和中-右-左得到的结果应该一样。
难点是如何递归?
错误代码:

class Solution {
public:
    bool compare(TreeNode* root1,TreeNode* root2)
    {
        if(root1->val==root2->val)
            return true;
        else
            return false;
        return compare(root1->left,root2->right);
        return compare(root1->right,root2->left);
    }
    bool isSymmetric(TreeNode* root) {
        TreeNode* root0=root;
        if(!root)
            return true;
        return compare(root0,root); 
    }
};

错误原因:
正确代码:
方法一:递归法

class Solution {
public:
    bool compare(TreeNode* root1,TreeNode* root2)
    {
        if(!root1&&!root2)
            return true;
        if(!root1||!root2)
            return false;
        return (root1->val==root2->val)&&compare(root1->left,root2->right)&&compare(root1->right,root2->left);
    }
    bool isSymmetric(TreeNode* root) {
        if(!root)
            return true;
        return compare(root,root); 
    }
};

方法二:迭代法
初始化时我们把根节点入队两次。每次提取两个结点并比较它们的值(队列中每两个连续的结点应该是相等的,而且它们的子树互为镜像),然后将两个结点的左右子结点按相反的顺序插入队列中。当队列为空时,或者我们检测到树不对称(即从队列中取出两个不相等的连续结点)时,该算法结束。

class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        if(!root)
            return true;
        queue<TreeNode*> s;
        s.push(root);
        s.push(root);
        while(!s.empty())
        {
            TreeNode* p=s.front();s.pop();
            TreeNode* q=s.front();s.pop();
            if(!p&&!q)
                continue;
            if((!p&&q)||(p&&!q)||(p->val!=q->val))
                return false;
            s.push(p->right);
            s.push(q->left);

            s.push(p->left);
            s.push(q->right);
        }
        return true;
    }
};

21 . 合并两个有序链表

错误代码:

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        if(!l1)
            return l2;
        if(!l2)
            return l1;
        while(l1->val>=l2->val)
        {
            ListNode* t=l2->next;
            l2->next=mergeTwoLists(l1,t);
        }
        while(l1->val<l2->val)
        {
            ListNode* t=l1->next;
            l1->next=mergeTwoLists(t,l2);
        }
        return l1;
    }
};

错误原因:不知道最后返回什么??
正确代码:

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        if(!l1)
            return l2;
        if(!l2)
            return l1;
        //自顶向下
        //头结点为l2
        if(l1->val>=l2->val)
        {
            //l2在前,比较l1和l2->next
            l2->next=mergeTwoLists(l1,l2->next);
            return l2;
        }
        //头结点为l1
        else
        {
            //l1在前,比较l1->next和l2
            l1->next=mergeTwoLists(l1->next,l2);
            return l1;
        }
    }
};

105. 从前序与中序遍历序列构造二叉树

完全没思路!根据根节点和左节点的位置顺序?如何构造?从下到上?
思路:
1、首先前序定位根节点;
2、在中序遍历找出对应根节点,并分辨出左右子树;
3、求左右子树长度,在前序遍历中找出子树;
4、递归。
逐个在前序找。然后中序找出索引。把那个索引的值的左边数组看为左子树,右边数组为右子树。

class Solution {
public:
    int indexit(vector<int>& vec,int p)
    {
        vector<int>::iterator it=find(vec.begin(),vec.end(),p);
        int dis=distance(vec.begin(),it);
        return dis;
    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        if(preorder.empty())
            return nullptr;
        TreeNode *newTree= new TreeNode(preorder[0]);//初始化根节点
        int loc=indexit(inorder,preorder[0]);//查找根节点在中序遍历中的位置
        int l1=loc,l2=preorder.size()-loc-1;//左子树、右子树的长度
        vector<int>leftTree(inorder.begin(),inorder.begin()+l1);//左子树结点中序
        vector<int>rightTree(inorder.end()-l2,inorder.end());//右子树结点中序

        vector<int>preleftTree(preorder.begin()+1,preorder.begin()+l1+1);//左子树前序
        vector<int>prerightTree(preorder.end()-l2,preorder.end());//右子树前序

        newTree->left=buildTree(preleftTree, leftTree);//递归子树
        newTree->right=buildTree(prerightTree, rightTree);
        return newTree;
    }
};
上一篇下一篇

猜你喜欢

热点阅读