给出一棵树的中序遍历和后序遍历,请构造这颗二叉树
注意:
保证给出的树中不存在重复的节点
class Solution {
public:
TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder)
{
int inLen = inorder.size(),postLen = postorder.size();
return dfs(inorder,0,inLen-1,postorder,0,postLen-1);
}
TreeNode * dfs(vector<int> &inorder,int inStart,int inEnd,vector<int> &postorder,int postStart,int postEnd)
{
if(inStart > inEnd)
return nullptr;
TreeNode *root = new TreeNode(postorder[postEnd]);
int middle;
for(middle=inStart;middle<=inEnd;++middle)
if(inorder[middle] == root->val)
break;
int leftLen = middle-inStart;
root->left = dfs(inorder,inStart,middle-1,postorder,postStart,postStart+leftLen-1);
root->right = dfs(inorder,middle+1,inEnd,postorder,postStart+leftLen,postEnd-1);
return root;
}
};
//不需要辅助函数,简单易懂
//后序遍历容器的最后一个数是根节点,中序遍历的根节点左边是左子树,右边是右子树,
//后序遍历左子树节点值相邻,右子树节点值也相邻。由后序遍历最后一个值将中序遍历分成
//左右两部分,再由这两部分的size将后序遍历分成左右两部分,递归即可
class Solution {
public:
TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder) {
if(inorder.empty())
return NULL;
int nodeval=postorder[postorder.size()-1];
TreeNode* head=new TreeNode(nodeval);
vector<int>::iterator iter=find(inorder.begin(),inorder.end(),nodeval);
vector<int>leftin=vector<int>(inorder.begin(),iter);
vector<int>rightin=vector<int>(iter+1,inorder.end());
int left=leftin.size();
int right=rightin.size();
if(left>0)
{
vector<int>leftpo=vector<int>(postorder.begin(),postorder.begin()+left);
head->left=buildTree(leftin,leftpo);
}
if(right>0)
{
vector<int>rightpo=vector<int>(postorder.begin()+left,postorder.begin()+left+right);
head->right=buildTree(rightin,rightpo);
}
return head;
}
};
class Solution {
public:
TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder) {
vector<int>::size_type lenIn = inorder.size();
vector<int>::size_type lenPost = postorder.size();
return buildTree_Aux(inorder,0,lenIn-1,postorder,0,lenPost-1);
}
TreeNode *buildTree_Aux(vector<int> &inorder,int inB,int inE,
vector<int> &postorder,int poB,int poE) {
if(inB > inE || poB > poE)
return NULL;
//在后序遍历中确定根节点
TreeNode* root = new TreeNode(postorder[poE]);
//在中序遍历中确定左右子树
vector<int>::iterator iter = find(inorder.begin()+inB,inorder.begin()+inE,postorder[poE]);
int index = iter - inorder.begin();
root->left = buildTree_Aux(inorder,inB,index-1,postorder,poB,poB+index-1-inB);
root->right = buildTree_Aux(inorder,index+1,inE,postorder,poB+index-inB,poE-1);
return root;
}
};
public class Solution {
private Map<Integer, Integer> indexForInOrders = new HashMap<>();
public TreeNode buildTree (int[] inorder, int[] postorder) {
for(int i = 0; i < inorder.length; i++)
{
indexForInOrders.put(inorder[i],i);
}
return Rebuid(postorder, 0, postorder.length - 1, 0);
}
public TreeNode Rebuid(int[] pos, int posL, int posR, int inL)
{
if(posL > posR) return null;
TreeNode root = new TreeNode(pos[posR]);
int index = indexForInOrders.get(root.val);
int leftTreeSize = index - inL;
root.left = Rebuid(pos, posL, posL + leftTreeSize - 1, inL);
root.right = Rebuid(pos, posL + leftTreeSize, posR - 1 , inL + leftTreeSize + 1);
return root;
}
} /*
* 目的:中+后->二叉树
* 思路:1.由后序遍历确定根节点。
* 2.在中序遍历中寻找根节点,然后将中序遍历分成左子树的中序遍历和右子树的中序遍历两部分。
* 3.根据左右子树中序遍历的数量,确定左右子树的后序遍历。
* 4.递归左右子树。
*/
TreeNode*getres(vector<int> &inorder, int ins, int ine, vector<int> &postorder, int posts,int poste){
if (ine-ins<0 || poste-posts<0)
return nullptr;
int pos = ins;
for(;pos<=ine;++pos){
if (inorder[pos]==postorder[poste])
break;
}
TreeNode*root = new TreeNode(postorder[poste]);
int len = pos-ins-1;
root->left = getres(inorder,ins,ins+len,postorder,posts,posts+len);
root->right = getres(inorder,ins+len+2,ine, postorder,posts+len+1, poste-1);
return root;
}
TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder) {
return getres(inorder,0,inorder.size()-1, postorder,0,postorder.size()-1);
}
public class Solution {
public TreeNode buildTree(int[] inorder, int[] postorder) {
return helper(inorder, postorder, 0, postorder.length - 1, 0, postorder.length - 1);
}
public TreeNode helper(int[] inorder, int[] postorder, int begin, int end, int postBegin, int postEnd){
if(begin > end) return null;
int value = postorder[postEnd];
TreeNode root = new TreeNode(value);
int mid = begin, postMid = postBegin;
for(int i = begin; i <= end; i++){
if(inorder[i] == value) break;
mid++;
postMid++;
}
root.left = helper(inorder, postorder, begin, mid - 1, postBegin, postMid - 1);
root.right = helper(inorder, postorder, mid + 1, end, postMid, postEnd - 1);
return root;
}
} /*
与先序,中序思路一样。
唯一不同的是,确定后序中左子树根节点,和右子树根节点比较麻烦。
*/
public class Solution {
private int[] inorder;
private int[] postorder;
public TreeNode buildTree(int[] inorder, int[] postorder) {
this.inorder = inorder;
this.postorder = postorder;
return decideNode(postorder.length - 1, 0, inorder.length - 1);
}
public TreeNode decideNode(int loc, int beg, int end) {
if (beg > end) return null;
int cnt = 0; //左子树的节点数。
int mid = 0;
for (int i = beg; i <= end; i++) {
if (postorder[loc] == inorder[i]) {
mid = i;
break;
}
cnt++;
}
TreeNode node = new TreeNode(postorder[loc]);
node.left = decideNode(loc - (end - beg + 1 - cnt), beg, mid - 1); //数量和坐标之间差1。
node.right = decideNode(loc - 1, mid + 1, end);
return node;
}
}
//C++迭代器
class Solution {
TreeNode* buildTree(vector<int>::iterator in_begin, vector<int>::iterator in_end, vector<int>::iterator post_begin, vector<int>::iterator post_end)
{
if (in_begin == in_end) {
return nullptr;
}
TreeNode* root = new TreeNode(*(post_end - 1));
auto it = find(in_begin, in_end, *(post_end - 1));
root->left = buildTree(in_begin, it, post_begin, post_begin + (it - in_begin));
root->right = buildTree(it + 1, in_end, post_begin + (it - in_begin), post_end - 1);
return root;
}
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder)
{
return buildTree(inorder.begin(), inorder.end(), postorder.begin(), postorder.end());
}
};
public class Solution {
public TreeNode buildTree(int[] inorder, int[] postorder) {
return dfs(inorder,0,inorder.length-1,postorder,0,postorder.length-1);
}
public TreeNode dfs(int[] inorder,int x,int y,int[] postorder,int i,int j) {
if(x>y||i>j) return null;
TreeNode root = new TreeNode(postorder[j]);
for(int cnt=x;cnt<=y;cnt++) {
if(inorder[cnt]==root.val) {
root.left = dfs(inorder,x,cnt-1,postorder,i,i+cnt-x-1);
root.right = dfs(inorder,cnt+1,y,postorder,i+cnt-x,j-1);
}
}
return root;
}
}
class Solution {
public:
TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder) {
return build(inorder,postorder,0,inorder.size()-1,0,postorder.size()-1);
}
TreeNode* build(vector<int> &inorder, vector<int> &postorder,int inbegin,int inend,int posbegin,int posend){
if(inbegin>inend||posbegin>posend)
return NULL;
TreeNode* root=new TreeNode(postorder[posend]);
for(int i=inbegin;i<=inend;i++){
if(inorder[i]==postorder[posend]){
root->left=build(inorder,postorder,inbegin,i-1,posbegin,posbegin+i-1-inbegin);
root->right=build(inorder,postorder,i+1,inend,posend-inend+i,posend-1);
}
}
return root;
}
};
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder) {
return create(inorder, postorder, 0, inorder.size()-1, 0, postorder.size()-1);
}
TreeNode* create(vector<int> &inorder, vector<int> &postorder, int is, int ie, int ps, int pe){
if(ps>pe) return NULL;
TreeNode* root = new TreeNode(postorder[pe]);
int mid;
for (int i=is; i<=ie;i++){
if (root->val==inorder[i]){
mid = i;
break;
}
}
root->left = create(inorder, postorder, is, mid-1, ps, ps+mid-is-1);
root->right = create(inorder, postorder, mid+1, ie, pe - ie + mid, pe - 1);
return root;
}
};
//root->left卡了好久。才想通,有点小纠结。
class Solution {
public:
TreeNode* func(vector<int> &in, vector<int> &pos, int start, int end, int head)
{
if(start >= end || head < 0) return NULL;
int mid = start;
for(;mid < end;mid++)
if(in[mid] == pos [head])
break;
if(mid >= end) return NULL;
TreeNode *root = new TreeNode(pos[head]);
root->left = func(in,pos,start,mid,head-end + mid);
root->right= func(in,pos,mid+1,end,head-1);
return root;
}
TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder) {
if(inorder.size() == 0 || postorder.size() == 0) return NULL;
return func(inorder,postorder,0,postorder.size(),postorder.size()-1);
}
};
class Solution {
public:
TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder) {
int l_in = inorder.size(),l_post = postorder.size();
return DFS(inorder,0,l_in-1,postorder,0,l_post-1);
}
TreeNode *DFS(vector<int> &inorder,int in_start,int in_end,vector<int> &postorder,int post_start,int post_end)
{
if(in_start > in_end)
return NULL;
TreeNode *root = new TreeNode(postorder[post_end]);
int mid;
for(mid=in_start;mid<=in_end;mid++)
{
if(inorder[mid] == root->val)
break;
}
int l_left = mid - in_start;
root->left = DFS(inorder,in_start,mid-1,postorder,post_start,post_start+l_left-1);
root->right = DFS(inorder,mid+1,in_end,postorder,post_start+l_left,post_end-1);
return root;
}
};
/**
* Definition for binary tree
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public TreeNode buildTree(int[] inorder, int[] postorder) {
if(inorder == null || postorder == null || inorder.length == 0 || postorder.length == 0)
return null;
return helpTree(inorder, 0, inorder.length - 1, postorder, 0, postorder.length - 1);
}
public TreeNode helpTree(int[] inorder, int beginin, int endin, int[] postorder, int beginpos, int endpos){
if(beginin > endin || beginpos > endpos)
return null;
// 后序遍历的最后一个元素为root,然后我们找到先序遍历的数组中
// root所在的位置,root前为左子树,后边为右子树
TreeNode root = new TreeNode(postorder[endpos]);
int inx = beginin;
for(int i = beginin; i <= endin; i++){
if(inorder[i] == postorder[endpos]){
inx = i;
break;
}
}
root.left = helpTree(inorder, beginin, inx - 1, postorder, beginpos, beginpos + inx - beginin - 1);
root.right = helpTree(inorder, inx + 1, endin, postorder, beginpos + inx - beginin, endpos - 1);
return root;
}
}
class Solution { public: TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder) { if(inorder.size() == 0)return NULL; TreeNode *p; TreeNode *root; stack<TreeNode *> stn; root = new TreeNode(postorder.back()); stn.push(root); postorder.pop_back(); while(true) { if(inorder.back() == stn.top()->val) { p = stn.top(); stn.pop(); inorder.pop_back(); if(inorder.size() == 0) break; if(stn.size() && inorder.back() == stn.top()->val) continue; p->left = new TreeNode(postorder.back()); postorder.pop_back(); stn.push(p->left); } else { p = new TreeNode(postorder.back()); postorder.pop_back(); stn.top()->right = p; stn.push(p); } } return root; } };
public class Solution {
public TreeNode buildTree(int[] inorder, int[] postorder) {
return createBinaryTree(inorder, 0, inorder.length - 1, postorder, 0, postorder.length - 1);
}
public TreeNode createBinaryTree(int[] inorder, int inLeft, int inRight, int[] postorder, int postLeft, int postRight) {
if(inLeft > inRight || postLeft > postRight) return null;
TreeNode root = new TreeNode(postorder[postRight]);
int len = 0;
for (int i = inLeft; i <= inRight; i ++) {
if(inorder[i] == postorder[postRight]) break;
len ++;
}
root.left = createBinaryTree(inorder, inLeft, inLeft + len - 1, postorder, postLeft, postLeft + len - 1);
root.right = createBinaryTree(inorder, inLeft + len + 1, inRight, postorder, postLeft + len, postRight - 1);
return root;
}
}
//和先序加中序构建二叉树是一样的,递归过程
public class 二叉树中序和后序遍历重构_106 {
public TreeNode buildTree(int[] inorder, int[] postorder) {
if (inorder==null||postorder==null||inorder.length==0) {
return null;
}
return ConstructTree(inorder,0,inorder.length-1,postorder,0,postorder.length-1);
}
private TreeNode ConstructTree(int[] inorder, int inStart, int inEnd,
int[] postorder, int postStart, int postEnd) {
if (inStart>inEnd||postStart>postEnd) {
return null;
}
TreeNode root=new TreeNode(postorder[postEnd]);
for (int i = 0; i < postorder.length; i++) {
if (inorder[i]==postorder[postEnd]) {
root.left=ConstructTree(inorder, inStart, i-1, postorder, postStart, postStart+i-1-inStart);
root.right=ConstructTree(inorder, i+1, inEnd, postorder, postStart+i-inStart, postEnd-1);
}
}
return root;
}
}
public TreeNode buildTree(int[] inorder, int[] postorder) {
if (inorder == null)
return null;
return buildTree(inorder, 0, inorder.length - 1, postorder, 0, postorder.length - 1);
}
private TreeNode buildTree(int[] inorder, int inLeft, int inRight, int[] postorder, int postLeft, int postRight) {
if (inLeft > inRight)
return null;
TreeNode root = new TreeNode(postorder[postRight]);
// 只有一个节点,返回root
if (inLeft == inRight)
return root;
int rootNum = 0;
for (int i = inLeft; i <= inRight; i++) {
if (inorder[i] == postorder[postRight]) {
rootNum = i;
break;
}
}
int leftLength = rootNum - inLeft;
//递归左子树和右子树
root.left = buildTree(inorder, inLeft, inLeft + leftLength - 1, postorder, postLeft, postLeft + leftLength - 1);
root.right = buildTree(inorder, inLeft + leftLength + 1, inRight, postorder, postLeft + leftLength,
postRight - 1);
return root;
}