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

题目描述

在这里插入图片描述

思路

根据前序历遍和中序历遍确定树。这里的思路是明确的。因为前序历遍,开头第一个元素就是树的根节点。在中序历遍中,确定了对应的根节点的位置,中序历遍中,根节点左边的全部元素构成树的左子树的节点,根节点右边的全部元素构成树的右子树的所有节点。
具体做法:

  1. 在先序前序历遍序列中找到树的根节点。
  2. 在中序历遍后找到树的树的根节点位置。
  3. 在前序历遍中,左子树的根节点为父节点之后的一个元素。由中序历遍中根节点的位置,可以知道左子树有多少个节点,由此可以在前序历遍中计算得到右子树的根节点的位置。
  4. 递归的调用就可以得到树。

解答

/**
 * 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:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        return fun(preorder,inorder,0,inorder.size()-1,0);
    }
    /*其中
    inorder_start是中序历遍序列的左端点
    i是中序历遍中根节点的位置
    inorder_end是中序历遍的序列的右端点
    */
    TreeNode* fun(vector<int>& preorder,vector<int>& inorder, int inorder_start, int inorder_end, int pre_root_index)
    {
        if(inorder_start==inorder_end) return new TreeNode(preorder[pre_root_index]);
        if(inorder_start>inorder_end) return NULL;
        int root_value=preorder[pre_root_index];
        TreeNode* root=new TreeNode(root_value);
        int i=0;
        for(;i<inorder.size();++i)
        {
            if(inorder[i]==root_value)
                break;
        }
        root->left=fun(preorder, inorder, inorder_start, i-1, pre_root_index+1);
        root->right=fun(preorder, inorder, i+1, inorder_end, pre_root_index+i-inorder_start+1);
        return root;
    }
};

总结:
其实这道题并不好理解,很容易出错,涉及好多边界条件的考虑。网上有一篇写得很好的博客,虽然他的方法并不好,涉及大量的内容占用。每次递归都需要生成新的数组序列用于递归。但是他的这种做法有一个好处就是容易让人理解这个题的思路。博客地址。

猜你喜欢

转载自blog.csdn.net/yuanliang861/article/details/83856587
今日推荐