zoukankan      html  css  js  c++  java
  • 《二叉树还原》

    首先我们需要知道的是中序遍历,因为这样我们才能知道根的左右子树,否则无法实现还原一棵唯一的二叉树。

    已知先序遍历,中序遍历,还原二叉树。

    我们知道先序遍历中第一次遇到的一定是根节点。

    然后我们就可以根据先序中的根节点位置,在中序遍历中取开辟左右子树。

    即递归取分解左右子树。

    按照中序的思想,我们会一直去找到左子树的根节点,所以在先序中一开始的一段一般都是左子树的根节点。

    具体的做法,就是在一段中先确定根的位置,然后就能左右去分解,然后找出下一次递归的下标和区间即可。

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
    public:
        void dfs(vector<int>& preorder, vector<int>& inorder,TreeNode* pre,int id,int pos,int L,int r) {
            if(L > r) return ;
            int rt = preorder[pos];
            int i = L;
            TreeNode* node = new TreeNode(rt);
            if(id == 0) pre->left = node;
            else pre->right = node;
            while(inorder[i] != rt) {
                ++i;
            }
            dfs(preorder,inorder,node,0,pos + 1,L,i - 1);
            dfs(preorder,inorder,node,1,pos + (i - L) + 1,i + 1,r);
        }
        TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
            TreeNode * rt = new TreeNode(0);
            int len = preorder.size();
            dfs(preorder,inorder,rt,0,0,0,len - 1);
            return rt->left;
        }
    };
    View Code

    已知后序遍历,中序遍历,还原二叉树。

     我们可以知道后序遍历一棵子树内的最后一个位置一定是根。

    所以我们每次分解子树的时候,都提取它的最后一个作为根,然后去递归分解。

    把范围都扣准就行。注意的是为了效率每次我们要去找根在中序中的位置,所以用map来提高速度。

    这里发现了一个问题,如果把map也作为形参去传递的话就会超时。

    猜测应该是因为map里的东西太多了,每次传递都要做一个拷贝,深度大了之后就超时了。

    所以开到全局去用。

    class Solution {
        int post_idx;
        unordered_map<int, int> mp;
    public:
        TreeNode* dfs(vector<int>& inorder, vector<int>& postorder,int le,int ri,int le2,int ri2) {
            if(le > ri || le2 > ri2) return nullptr;
            int pos = mp[postorder[ri2]];
            TreeNode* node = new TreeNode(postorder[ri2]);
            node->left = dfs(inorder,postorder,le,pos - 1,le2,le2 + (pos - le - 1));
            node->right =  dfs(inorder,postorder,pos + 1,ri,le2 + (pos - le),ri2 - 1);
            return node;
        }
        TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
            int idx = 0;
            for (auto& val : inorder) {
                mp[val] = idx++;
            }
            return dfs(inorder,postorder,0, (int)inorder.size() - 1,0, (int)inorder.size() - 1);
        }
    };
    View Code
  • 相关阅读:
    将字符串按指定间隔分隔
    C#汉字转化为拼音
    Silverlight客户端分页 DataPager控件的使用
    c# EnumUtil
    【AS3代码】通过两者间的距离,检测是否碰撞
    【AS3代码】遮罩用法
    【AS3代码】XML操作
    【AS3代码】数组知识
    【AS3代码】深度的设置
    【AS3代码】模仿现实世界中(地球重力)的甩球游戏
  • 原文地址:https://www.cnblogs.com/zwjzwj/p/14690144.html
Copyright © 2011-2022 走看看