目录
- 1- 思路
- 递归
- 2- 实现
- ⭐105. 从前序与中序遍历序列构造二叉树——题解思路
- 3- ACM 实现
- 原题连接:105. 从前序与中序遍历序列构造二叉树
1- 思路
递归
- 前序:中左右
- 中序:左中右
让前序的第一个元素作为中序的分割点
分割思路
- 1- 递归参数与返回值(递归的指针是左闭右开的 也就是
[left,right)
的)preOrder
前序数组;pLeft
中序数组左指针 用于切割;pRight
:中序数组右指针 用于切割inOrder
前序数组;iLeft
前序数组左指针 用于切割;iRight
:前序数组右指针 用于切割
TreeNode build(int[] preOrder,int pLeft,int pRight,int[] inOrder,int iLeft,int iRight)
- 2- 终止条件
- 两个 指针相遇时终止
- 3- 树构造
- 3.1 先找根:前序:
中左右
、中序:左中右
,所以根节点一定是,前序数组的第一个元素 - 3.2 去中序找 mid:用
iLeft
和iRight
去定位寻找,定位值为mid
- 3.3 中序数组拆分
iLfeft1 = iLfeft;
iRight1 = mid;
iLeft2 = mid+1;
iRight2 = iRight;
- 3.4 前序数组拆分
pLeft1 = pLeft+1;
pRight1 = pLeft + (mid-iLeft1)+1;
pLeft2 = pRight1;
pRight2 = pRight;
- 3.5 递归实现
- 递归构造当前根节点的左子树和右子树
- 左子树构造:
root.left = build(preOrder,pLeft1,pRight1,inOrder,iLfeft1,iRight1);
- 右子树构造:
root.right = build(preOrder,pLeft2,pRight2,inOrder,iLfeft2,iRight2);
2- 实现
⭐105. 从前序与中序遍历序列构造二叉树——题解思路
/*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val = val; }* TreeNode(int val, TreeNode left, TreeNode right) {* this.val = val;* this.left = left;* this.right = right;* }* }*/
class Solution {public TreeNode buildTree(int[] preorder, int[] inorder) {if(inorder.length==0){return null;}return build(preorder,0,preorder.length,inorder,0,inorder.length);}public TreeNode build(int[] preorder,int pLeft,int pRight,int[] inorder,int iLeft,int iRight){// 终止条件if(pLeft == pRight){return null;}// 找根int rootVal = preorder[pLeft];TreeNode root = new TreeNode(rootVal);// 定位midint mid = 0;for(mid=iLeft ; mid<iRight;mid++){if(inorder[mid]==rootVal){break;}}// 拆中序int iLeft1 = iLeft;int iRight1 = mid;int iLeft2 = mid+1;int iRight2 = iRight;// 拆前序int pLeft1 = pLeft+1;int pRight1 = pLeft+(mid-iLeft1)+1;int pLeft2 = pRight1;int pRight2 = pRight;// 构造root.left = build(preorder,pLeft1,pRight1,inorder,iLeft1,iRight1);root.right = build(preorder,pLeft2,pRight2,inorder,iLeft2,iRight2);return root;}
}
3- ACM 实现
public class buildTree {public static class TreeNode {int val;TreeNode left;TreeNode right;TreeNode() {}TreeNode(int val) { this.val = val; }TreeNode(int val, TreeNode left, TreeNode right) {this.val = val;this.left = left;this.right = right;}}public static TreeNode buildBy(int[] preOrder,int[] inOrder){// 调用递归buildreturn build(preOrder,0,preOrder.length,inOrder,0,inOrder.length);}// 递归实现public static TreeNode build(int[] preOrder,int pLeft,int pRight,int[] inOrder,int iLeft,int iRight){//1. 终止条件if(pLeft==pRight){return null;}// 2. 构造根节点int rootVal = preOrder[pLeft];TreeNode root = new TreeNode(rootVal);// 3.定位midint mid = 0;for(mid = iLeft;mid<iRight;mid++){if(inOrder[mid]==rootVal){break;}}// 拆分中序int iLeft1 = iLeft;int iRight1 = mid;int iLeft2 = mid+1;int iRight2 = iRight;// 拆分前序int pLeft1 = pLeft+1;int pRight1 = pLeft+(mid-iLeft1)+1;int pLeft2 = pRight1;int pRight2 = pRight;// 递归构造root.left = build(preOrder,pLeft1,pRight1,inOrder,iLeft1,iRight1);root.right = build(preOrder,pLeft2,pRight2,inOrder,iLeft2,iRight2);return root;}static List<List<Integer>> res = new ArrayList<>();public static List<List<Integer>> levelOrder(TreeNode root) {if(root==null){return res;}// 队列Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);while(!queue.isEmpty()){int len = queue.size();List<Integer> path = new ArrayList<>();while(len>0){TreeNode nowNode = queue.poll();path.add(nowNode.val);if(nowNode.left!=null) queue.offer(nowNode.left);if(nowNode.right!=null) queue.offer(nowNode.right);len--;}res.add(new ArrayList<>(path));}return res;}public static void main(String[] args) {Scanner sc = new Scanner(System.in);String[] pOrder = sc.nextLine().replace("[","").replace("]","").split(",");String[] iOrder = sc.nextLine().replace("[","").replace("]","").split(",");int[] pNum = new int[pOrder.length];int[] iNum = new int[iOrder.length];for(int i = 0 ; i < pOrder.length;i++){pNum[i] = Integer.parseInt(pOrder[i]);iNum[i] = Integer.parseInt(iOrder[i]);}TreeNode root = buildBy(pNum,iNum);levelOrder(root);System.out.println("结果是"+res.toString());}
}