- 原题连接: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);
// 定位mid
int 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){
// 调用递归build
return 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.定位mid
int 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());
}
}