给定一个二叉树的中序与后序遍历结果,请你根据两个序列构造符合这两个序列的二叉树。
数据范围:二叉树的节点数满足 ,节点上的值满足 ,保证节点的值各不相同
例如输入[2,1,4,3,5],[2,4,5,3,1]时,
根据中序遍历的结果[2,1,4,3,5]和后序遍历的结果[2,4,5,3,1]可构造出二叉树{1,2,3,#,#,4,5},如下图所示:
[1],[1]
{1}
[2,1,4,3,5],[2,4,5,3,1]
{1,2,3,#,#,4,5}
import java.util.*; /* * public class TreeNode { * int val = 0; * TreeNode left = null; * TreeNode right = null; * public TreeNode(int val) { * this.val = val; * } * } */ public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param inorder int整型一维数组 中序遍历序列 * @param postorder int整型一维数组 后序遍历序列 * @return TreeNode类 */ public TreeNode buildTree (int[] inorder, int[] postorder) { // write code here if(inorder.length != postorder.length || inorder == null || inorder.length == 0) return null; int rootVal = postorder[postorder.length - 1]; // 后序遍历的最后一个元素是根节点 TreeNode tree = new TreeNode(rootVal); // 构建根节点 // 找到根节点在中序遍历中的位置 int rootIndex = 0; for(int i = 0; i < inorder.length; i++){ if(inorder[i] == rootVal){ rootIndex = i; break; } } // 将序列划分为左右两个子树部分,分别进行重构 tree.left = buildTree(Arrays.copyOfRange(inorder, 0, rootIndex), Arrays.copyOfRange(postorder, 0, rootIndex)); tree.right = buildTree(Arrays.copyOfRange(inorder, rootIndex + 1, inorder.length), Arrays.copyOfRange(postorder, rootIndex, postorder.length - 1)); return tree; } }
/** * struct TreeNode { * int val; * struct TreeNode *left; * struct TreeNode *right; * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * }; */ class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param inorder int整型vector 中序遍历序列 * @param postorder int整型vector 后序遍历序列 * @return TreeNode类 */ TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) { // write code here if (postorder.empty()) return nullptr; TreeNode *root = new TreeNode(postorder[postorder.size() - 1]); vector<int> left, right; for (int i = 0; i < inorder.size(); ++i) { if (inorder[i] == root->val) { // left vector<int> left_in(inorder.begin(), inorder.begin() + i); vector<int> left_post(postorder.begin(), postorder.begin() + i); root->left = buildTree(left_in, left_post); // right vector<int> right_in(inorder.begin() + i + 1, inorder.end()); vector<int> right_post(postorder.begin() + i, postorder.end() - 1); root->right = buildTree(right_in, right_post); } } return root; } };
int post_idx; TreeNode* build(int i1, int i2, vector<int>& inorder, vector<int>& postorder){ if(i1 > i2) return nullptr; vector<int>::iterator it = find(inorder.begin() + i1, inorder.begin() + i2 + 1, postorder[post_idx]); int idx = distance(inorder.begin(), it); TreeNode *newNode = new TreeNode(inorder[idx]); post_idx --; newNode->right = build(idx +1, i2, inorder, postorder); newNode->left = build(i1, idx - 1, inorder, postorder); return newNode; } TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) { post_idx = postorder.size() - 1; return build(0, inorder.size() - 1, inorder, postorder); }
package main //import "fmt" import . "nc_tools" /* * type TreeNode struct { * Val int * Left *TreeNode * Right *TreeNode * } */ /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param inorder int整型一维数组 中序遍历序列 * @param postorder int整型一维数组 后序遍历序列 * @return TreeNode类 */ func buildTree( inorder []int , postorder []int ) *TreeNode { // write code here if len(postorder) == 0{ return nil } newNode := new(TreeNode) newNode.Val = postorder[len(postorder) - 1] for i := 0; i < len(inorder); i++{ if newNode.Val == inorder[i]{ newNode.Left = buildTree(inorder[:i], postorder[:i]) newNode.Right = buildTree(inorder[i+1:], postorder[i:len(postorder)-1]) return newNode } } return newNode }
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) { // write code here if(inorder.size()==0||postorder.size()==0) return nullptr; int x=*postorder.rbegin(); TreeNode *root=new TreeNode(x); int post; for(int i=0;i<inorder.size();i++) { if(inorder[i]==x) post=i; } vector<int> lin; vector<int> rin; for(int i=0;i<post;i++) lin.push_back(inorder[i]); for(int i=post+1;i<inorder.size();i++) rin.push_back(inorder[i]); vector<int>lpost; vector<int>rpost; for(int i=0;i<post;i++)lpost.push_back(postorder[i]); for(int i=post;i<postorder.size()-1;i++)rpost.push_back(postorder[i]); root->left=buildTree(lin, lpost); root->right=buildTree(rin, rpost); return root; }
/** * struct TreeNode { * int val; * struct TreeNode *left; * struct TreeNode *right; * }; */ #include <stdlib.h> void build_root(struct TreeNode** root,int* inorder,int left1,int right1,int* postorder, int* idx){ if(left1 > right1 || *idx == -1){ return; } *root = malloc(sizeof(struct TreeNode)); printf("%d ",postorder[*idx]); (*root)->val = postorder[*idx]; (*idx)--; (*root)->left = NULL; (*root)->right = NULL; //找到postOrder[*idx]在inorder的位置 for(int i = left1; i <= right1;i++){ if(inorder[i] == (*root)->val){ //找到 //判断*idx 是否已经走完 if(*idx != -1){ //判断下一个根节点的位置是在inorder[i]的左边还是右边 int flag = 1;//1右边,0左边 for(int j = left1; j <= i;j++){ if(inorder[i] ==postorder[*idx]){ //在左边 flag = 0; break; } } if(flag == 0){ build_root(&((*root)->left), inorder, left1, i-1,postorder, idx); build_root(&((*root)->right), inorder, i+1, right1,postorder, idx); } else { build_root(&((*root)->right), inorder, i+1, right1,postorder, idx); build_root(&((*root)->left), inorder, left1, i-1,postorder, idx); } } break; } } } /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param inorder int整型一维数组 中序遍历序列 * @param inorderLen int inorder数组长度 * @param postorder int整型一维数组 后序遍历序列 * @param postorderLen int postorder数组长度 * @return TreeNode类 */ struct TreeNode* buildTree(int* inorder, int inorderLen, int* postorder, int postorderLen ) { // write code here //记录节点数为1000个,记录输入值中 struct TreeNode* root; int idx = postorderLen-1; build_root(&root, inorder, 0, inorderLen - 1, postorder,&idx); return root; }
import java.util.*; /* * public class TreeNode { * int val = 0; * TreeNode left = null; * TreeNode right = null; * public TreeNode(int val) { * this.val = val; * } * } */ public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param inorder int整型一维数组 中序遍历序列 * @param postorder int整型一维数组 后序遍历序列 * @return TreeNode类 */ public TreeNode buildTree (int[] inorder, int[] postorder) { // write code here return build(inorder, 0, inorder.length - 1, postorder, 0, postorder.length - 1); } // 左 中 右 // 左 右 中 private TreeNode build(int[] inOrder, int li, int ri, int[] postorder, int lp, int rp) { if(li > ri) return null; TreeNode cur = new TreeNode(postorder[rp]); int i = li; for(; i <= ri; i++) { if(inOrder[i] == postorder[rp]) break; } cur.left = build(inOrder, li, i - 1, postorder, lp, lp + i - li - 1); // ri - i - 1 cur.right = build(inOrder, i + 1, ri, postorder, rp - ri + i, rp - 1); return cur; } }
#include <stdio.h> #include <string.h> #include <stdlib.h> struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; }; /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param inorder int整型一维数组 中序遍历序列 * @param inorderLen int inorder数组长度 * @param postorder int整型一维数组 后序遍历序列 * @param postorderLen int postorder数组长度 * @return TreeNode类 */ struct TreeNode* buildTree(int* inorder, int inorderLen, int* postorder, int postorderLen ) { // write code here if (inorderLen < 1 || postorderLen < 1)return NULL; struct TreeNode* root = (struct TreeNode*)malloc(sizeof(struct TreeNode)); root->val = postorder[postorderLen - 1]; int* p = inorder; for (; p < inorder + inorderLen; p++) { if (*p == postorder[postorderLen - 1]) break; } int k = p - inorder; //左子树结点数量 //递归构建左子树:中序开始位置inorder,后序开始位置postorder root->left = buildTree(inorder, k, postorder, k); //右子树结点数量inorderLen - k - 1 //递归构建右子树:中序开始位置p+1,后序开始位置postorder+k root->right = buildTree(p + 1, inorderLen - k - 1, postorder + k, inorderLen - k - 1); return root; } //前序遍历 void preOrder(struct TreeNode* root) { if (root) { printf("%d ", root->val); preOrder(root->left); preOrder(root->right); } } int main(int argc, char *argv[]) { int inorder[] = {2, 1, 4, 3, 5}; int postorder[] = {2, 4, 5, 3, 1}; int n = sizeof(inorder) / sizeof(int); struct TreeNode* root = buildTree(inorder, n, postorder, n); preOrder(root); printf("\n"); return 0; }
/** * struct TreeNode { * int val; * struct TreeNode* left; * struct TreeNode* right; * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * }; */ class Solution { int post_idx; // 从后序遍历的 最后一个元素开始 unordered_map<int, int> idx_map;// 建立(中序元素,后序下标)键值对的哈希表 public: TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) { // 从后序遍历的最后一个元素开始 post_idx = (int)postorder.size()-1; int idx = 0; // 建立(中序元素,中序下标)键值对的哈希表 for (auto& val : inorder) idx_map[val] = idx++; return helper(0, (int)inorder.size()-1, inorder, postorder); } TreeNode* helper(int in_left, int in_right, vector<int>& inorder, vector<int>& postorder){ if (in_left > in_right) // 如果这里没有节点构造二叉树了,就结束 return nullptr; int root_val = postorder[post_idx]; //1 选择post_idx位置的元素,作为当前子树 根节点 post_idx--; // 下标减一 TreeNode* root = new TreeNode(root_val); // 根节点 int index = idx_map[root_val]; //2 根据root所在中序的index,将中序分成左右两棵子树 root->right = helper(index+1, in_right, inorder, postorder); // 1构造root节点的右子树 root->left = helper(in_left, index-1, inorder, postorder); // 2构造root节点的左子树 return root; // 根节点 } };
/** * struct TreeNode { * int val; * struct TreeNode *left; * struct TreeNode *right; * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * }; */ #include <unordered_map> class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param inorder int整型vector 中序遍历序列 * @param postorder int整型vector 后序遍历序列 * @return TreeNode类 */ TreeNode* buildTreehelper(vector<int>& inorder, int instart, int inend, vector<int>& postorder, int poststart, int postend, unordered_map<int, int>& map){ if(instart > inend || poststart > postend){ return nullptr; // 递归终止条件 } // 在后续数组中找根节点 TreeNode* root = new TreeNode(postorder[postend]); int rootIndex = map[postorder[postend]]; // 根据中序数组分割左右子树 // 中序数组中的左片段[instart, rootIndex - 1] *** // 中序数组中的右片段[rootIndex + 1, inend] // 后续数组中的左片段[poststart, poststart + (rootIndex - instart) - 1] *** // 后续数组中的右片段[poststart + (rootIndex - instart), postend - 1] root->left = buildTreehelper(inorder, instart, rootIndex - 1, postorder, poststart, poststart + (rootIndex - instart) - 1, map); root->right = buildTreehelper(inorder, rootIndex + 1, inend, postorder, poststart + (rootIndex - instart), postend - 1, map); return root; } TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) { // 先把中序数组的位置用哈希表存起来,方便查找 unordered_map<int, int> map; for(int i = 0; i < inorder.size(); i++){ map[inorder[i]] = i; } return buildTreehelper(inorder, 0, inorder.size()-1, postorder, 0, postorder.size()-1, map); } };
/* * function TreeNode(x) { * this.val = x; * this.left = null; * this.right = null; * } */ /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param inorder int整型一维数组 中序遍历序列 * @param postorder int整型一维数组 后序遍历序列 * @return TreeNode类 */ function buildTree( inorder , postorder ) { if(postorder.length==0) return null; let root_val=postorder[postorder.length-1]; let idx=inorder.indexOf(root_val); let root=new TreeNode(root_val); root.left=buildTree(inorder.slice(0,idx),postorder.slice(0,idx)); root.right=buildTree(inorder.slice(idx+1),postorder.slice(idx,postorder.length-1)); return root; } module.exports = { buildTree : buildTree };
Map<Integer, Integer> inOrderMap; int[] postOrder; int postIdx; public TreeNode buildTree(int[] inorder, int[] postorder) { // 将中序下标放入Map中 Map<Integer, Integer> inOrderMap = new HashMap<>(); for (int i=0; i<inorder.length; i++) { inOrderMap.put(inorder[i], i); } this.inOrderMap = inOrderMap; this.postIdx = postorder.length-1; this.postOrder = postorder; return build(0, inorder.length-1); } public TreeNode build(int leftIdx, int rightIdx) { if (leftIdx > rightIdx) { return null; } int rootVal = postOrder[postIdx--]; int rootIdx = inOrderMap.get(rootVal); TreeNode root = new TreeNode(rootVal); // 通过后序遍历往前推,所以先处理右子树 // 中序遍历,root点的右边是右子树,左边是左子树 root.right = build(rootIdx+1, rightIdx); root.left = build(leftIdx, rootIdx-1); return root; }
typedef struct TreeNode TreeNode; TreeNode* tree(int* inorder, int inL,int inR, int* postorder, int postL,int postR); struct TreeNode* buildTree(int* inorder, int inorderLen, int* postorder, int postorderLen ) { // write code here return tree(inorder,0,inorderLen-1,postorder,0,postorderLen-1); } //递归法构造 TreeNode* tree(int* inorder, int inL,int inR, int* postorder, int postL,int postR) { if(postL>postR) return NULL; TreeNode* node = malloc(sizeof(TreeNode)); node->val=postorder[postR]; int pos = inL; while(pos<=inR && inorder[pos]!=node->val) { ++pos; } node->left = tree(inorder, inL, pos-1, postorder, postL, postL+pos-inL-1); node->right = tree(inorder, pos+1, inR, postorder, postL+pos-inL, postR-1); return node; }
int[] post; HashMap<Integer,Integer> inorderMap = new HashMap<Integer,Integer>(); public TreeNode buildTree (int[] inorder, int[] postorder) { for(int i = 0;i<inorder.length;i++){ inorderMap.put(inorder[i],i); } // write code here post = postorder; int len = inorder.length; return build(0,len - 1,0,len -1); } private TreeNode build(int inleft,int inright,int postleft,int postright){ if(inleft > inright || postleft > postright){ return null; } int value = post[postright]; int index = inorderMap.get(value); TreeNode root = new TreeNode(value); root.left = build(inleft,index - 1,postleft,postleft+index-inleft -1); root.right = build(index+1,inright,postleft+index-inleft,postright -1); return root; }
思路:
1.中序遍历顺序:左根右;后序遍历顺序:左右根;根据给出的后序遍历数组可知,数组末元素为根结点值;取出该结点,作为根结点的值。
2.根据中序遍历顺序,找出根结点位置rootIdx;在中序遍历数组中,该结点左边元素为左子树结点值,右边为右子树结点值;在后序遍历数组中,可知从0到rootIdx为左子树结点,从rootIdx到倒数第二个元素为右子数结点。
3.根据中序遍历左子数,后序遍历左子数数组初始化左子树,作为根结点的左子树;根据中序遍历右子数,后序遍历右子数数组初始化右子树,作为根结点的右子树;
4.返回根结点
class Solution: def buildTree(self , inorder: List[int], postorder: List[int]) -> TreeNode: # write code here if postorder: ind=inorder.index(postorder[-1]) root=TreeNode(postorder.pop()) root.left=self.buildTree(inorder[:ind],postorder[:ind])#左都同 root.right=self.buildTree(inorder[ind+1:],postorder[ind:]) return root
public class Solution { public TreeNode buildTree (int[] inorder, int[] postorder) { for (int i = 0; i < inorder.length; i++) map.put(inorder[i], i); return help(inorder, 0, inorder.length-1, postorder, 0, postorder.length-1); } public Map<Integer, Integer> map = new HashMap<>(); public TreeNode help(int[] inorder, int inStart, int inEnd, int[] postorder, int postStart, int postEnd) { if (inStart > inEnd) return null; int idx = map.get(postorder[postEnd]); int l = idx - inStart; TreeNode root = new TreeNode(postorder[postEnd]); root.left = help(inorder, inStart, idx-1, postorder, postStart, postStart+l-1); root.right = help(inorder, idx+1, inEnd, postorder, postStart+l, postEnd-1); return root; } }