leetcode 从中序与后序序列 or 从前序与中序序列 构造二叉树 java
- 前序pre:root、left、right
- 中序in:left、root、right
- 后序post:left、right、root
算法过程
- 构造HashMap,将inorder存储在map中
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < inorder.length; i++) { // 用map保存中序序列的数值对应位置map.put(inorder[i], i);}
- 构造
findNode
函数
中序与后序序列:findNode(int[] inorder, int inBegin, int inEnd, int[] postorder, int postBegin, int postEnd)
前序与后序序列:findNode(int[] preorder, int preBegin, int preEnd, int[] inorder, int inBegin, int inEnd)
2.1 判断有没有元素,没有的话返回null
2.2 找到前序遍历的第一个元素or 后序遍历的最后一个元素在中序遍历中的位置
int rootIndex = map.get(preorder[preBegin]);
int rootIndex = map.get(postorder[postEnd-1]);
2.3 构造root节点
TreeNode root = new TreeNode(inorder[rootIndex]);
2.4 保存中序左子树个数,用来确定后序数列的个数
int lenOfLeft = rootIndex-inBegin;
2.5 创建root.left和root.right
中序与后序序列:
root.left = findNode(inorder, inBegin, rootIndex, postorder, postBegin, postBegin+lenOfLeft);
root.right = findNode(inorder,rootIndex+1,inEnd, postorder, postBegin+lenOfLeft,postEnd-1);
前序与中序序列:
root.left = findNode(preorder,preBegin+1,preBegin+lenOfLeft+1,inorder,inBegin,rootIndex);
root.right= findNode(preorder,preBegin+lenOfLeft+1,preEnd,inorder,rootIndex+1,inEnd);
2.6 return root;
完整代码:
从中序与后序遍历序列构造二叉树
class Solution {Map<Integer, Integer> map; // 方便根据数值查找位置public TreeNode buildTree(int[] inorder, int[] postorder) {map = new HashMap<>();for (int i = 0; i < inorder.length; i++) { // 用map保存中序序列的数值对应位置map.put(inorder[i], i);}return findNode(inorder, 0, inorder.length, postorder,0, postorder.length); // 前闭后开}public TreeNode findNode(int[] inorder, int inBegin, int inEnd, int[] postorder, int postBegin, int postEnd) {// 参数里的范围都是前闭后开if (inBegin >= inEnd || postBegin >= postEnd) { // 不满足左闭右开,说明没有元素,返回空树return null;}int rootIndex = map.get(postorder[postEnd - 1]); // 找到后序遍历的最后一个元素在中序遍历中的位置TreeNode root = new TreeNode(inorder[rootIndex]); // 构造结点int lenOfLeft = rootIndex - inBegin; // 保存中序左子树个数,用来确定后序数列的个数root.left = findNode(inorder, inBegin, rootIndex,postorder, postBegin, postBegin + lenOfLeft);root.right = findNode(inorder, rootIndex + 1, inEnd,postorder, postBegin + lenOfLeft, postEnd - 1);return root;}
}
从前序与中序遍历序列构造二叉树
class Solution {Map<Integer, Integer> map;public TreeNode buildTree(int[] preorder, int[] inorder) {map = new HashMap<>();for (int i = 0; i < inorder.length; i++) { // 用map保存中序序列的数值对应位置map.put(inorder[i], i);}return findNode(preorder, 0, preorder.length, inorder, 0, inorder.length); // 前闭后开}public TreeNode findNode(int[] preorder, int preBegin, int preEnd, int[] inorder, int inBegin, int inEnd) {// 参数里的范围都是前闭后开if (preBegin >= preEnd || inBegin >= inEnd) { // 不满足左闭右开,说明没有元素,返回空树return null;}int rootIndex = map.get(preorder[preBegin]); // 找到前序遍历的第一个元素在中序遍历中的位置TreeNode root = new TreeNode(inorder[rootIndex]); // 构造结点int lenOfLeft = rootIndex - inBegin; // 保存中序左子树个数,用来确定前序数列的个数root.left = findNode(preorder, preBegin + 1, preBegin + lenOfLeft + 1,inorder, inBegin, rootIndex);root.right = findNode(preorder, preBegin + lenOfLeft + 1, preEnd,inorder, rootIndex + 1, inEnd);return root;}