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