写树的算法,关键思路如下:
把题目的要求细化,搞清楚根节点应该做什么,然后剩下的事情抛给前/中/后序的遍历框架就行了,我们千万不要跳进递归的细节里,你的脑袋才能压几个栈呀。
题目链接:
leetcode105 从前序与中序遍历序列构造二叉树
本题思路:
函数签名如下:
TreeNode buildTree(int[] preorder, int[] inorder);
首先思考,根节点应该做什么。确定根节点的值,把根节点做出来,然后递归构造左右子树即可。
preorder第一个元素为root,在inorder里面找到root,在它之前的为左子树(长leftSize),之后为右子树。preorder[1]到preorder[leftSize]为左子树,之后为右子树,分别递归。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
return build(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);
}
public TreeNode build(int[] preorder, int preStart, int preEnd, int[] inorder, int inStart, int inEnd) {
// base case
if (preStart > preEnd) return null;
// 先找到根节点的值,即为前序遍历数组中第一个数
int rootVal = preorder[preStart];
// 确定该值在中序遍历数组中的位置,记录下标
int index = 0;
for(int i = inStart; i <= inEnd; i++) {
if(inorder[i] == rootVal) {
index = i;
break;
}
}
// 记录左子树长度
int leftSize = index - inStart;
// 构造根节点
TreeNode root = new TreeNode(rootVal);
// 递归构造左右子树
root.left = build(preorder, preStart + 1, preStart + leftSize, inorder, inStart, index - 1);
root.right = build(preorder, preStart + leftSize + 1, preEnd, inorder, index + 1, inEnd);
return root;
}
}