例如已知先序遍历求中序遍历;
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
思路其实挺简单的,每次在pre中找根结点,在inorder找左节点与右节点
#include <iostream>
#include<vector>
using namespace std;
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution {
private:
TreeNode* _buildTree(vector<int>& preorder, int preLeft, int preRight, vector<int>& inorder, int inLeft, int inRight)
{
if (preLeft>preRight||inLeft>inRight)
{
return nullptr;
}
TreeNode *root = new TreeNode(preorder[preLeft]);
int index;
for (index = inLeft;index <= inRight;index++)//找到了先序在中序中的位置
{
if (preorder[preLeft]==inorder[index])
{
break;
}
}
root->left= _buildTree(preorder, preLeft+1, preLeft+ index -inLeft, inorder, inLeft, index-1);
root->right = _buildTree(preorder, preLeft + index - inLeft + 1, preRight, inorder, index + 1, inRight);
return root;
}
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder)
{
int preLeft = 0;
int preRight = preorder.size() - 1;
int inLeft = 0;
int inRight = inorder.size() - 1;
return _buildTree(preorder, preLeft, preRight, inorder, inLeft, inRight);
}
};
当然每次根据pre在in中找位置可能太浪费时间,我们采用空间换时间,采用unorderrd_map存取中序的位置
class Solution {
private:
TreeNode* _buildTree(vector<int>& preorder, int preLeft, int preRight, unordered_map<int, int> &index_map, int inLeft, int inRight)
{//index_map 必须用引用,可能内存占用大
if (preLeft>preRight||inLeft>inRight)
{
return nullptr;
}
TreeNode *root = new TreeNode(preorder[preLeft]);
int index= index_map[preorder[preLeft]];
root->left= _buildTree(preorder, preLeft+1, preLeft+ index -inLeft, index_map, inLeft, index-1);
root->right = _buildTree(preorder, preLeft + index - inLeft + 1, preRight, index_map, index + 1, inRight);
return root;
}
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder)
{
int preLeft = 0;
int preRight = preorder.size() - 1;
int inLeft = 0;
int inRight = inorder.size() - 1;
unordered_map<int, int> index_map;
for (int i = 0;i < inorder.size();i++)
{
index_map[inorder[i]] = i;
}
return _buildTree(preorder, preLeft, preRight, index_map, inLeft, inRight);
}
};
当然还有 已知后序和中序,建立二叉树。
思路一样首先在后序中倒数第一个是根,然后在中序中找左右子节点,递归
代码如下:
/**
* 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 {
private:
TreeNode* _buildTree(vector<int>& postorder, int posLeft, int posRight, vector<int>& inorder, int inLeft, int inRight)
{
if (posLeft > posRight || inLeft > inRight)
{
return nullptr;
}
TreeNode *root = new TreeNode(postorder[posRight]);
int index;
for (index=inLeft;index<=inRight;index++)//由于是后序遍历,所以是左右根
{
if (postorder[posRight]==inorder[index])
{
break;
}
}
root->left= _buildTree(postorder, posLeft, posRight+index-inRight-1, inorder, inLeft, index-1);
root->right = _buildTree(postorder, posRight + index - inRight, posRight - 1, inorder, index +1,inRight);
return root;
//
}
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder)
{
int posLeft = 0;
int posRight = postorder.size() - 1;
int inLeft = 0;
int inRight = inorder.size() - 1;
return _buildTree(postorder, posLeft, posRight, inorder, inLeft, inRight);
}
};
当然也可以进行优化采用undered_map保存中序的数值和下标的关系
#include <iostream>
#include<vector>
#include<unordered_map>
using namespace std;
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution {
private:
TreeNode* _buildTree(vector<int>& postorder, int posLeft, int posRight, unordered_map<int, int> &index_map, int inLeft, int inRight)
{
if (posLeft > posRight || inLeft > inRight)
{
return nullptr;
}
TreeNode *root = new TreeNode(postorder[posRight]);
int index= index_map[postorder[posRight]];
root->left= _buildTree(postorder, posLeft, posRight+index-inRight-1, index_map, inLeft, index-1);
root->right = _buildTree(postorder, posRight + index - inRight, posRight - 1, index_map, index +1,inRight);
return root;
//
}
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder)
{
int posLeft = 0;
int posRight = postorder.size() - 1;
int inLeft = 0;
int inRight = inorder.size() - 1;
unordered_map<int, int> index_map;
for (int i = 0;i < inorder.size();i++)
{
index_map[inorder[i]] = i;
}
return _buildTree(postorder, posLeft, posRight, index_map, inLeft, inRight);
}
};