常见的构建二叉树的题目有:
1.利用先序(或后序)和中序遍历构建二叉树
2.利用有序联表或数组构建平衡二叉树
解决这类问题通常采用递归方式,而递归方法要做的事,就是找到根节点。
类型1的题目,根节点为先序遍历的第一位(后序遍历的最后一位),找到根节点之后,我们利用递归找左子树的根。中序遍历具有一个特点,那就是根节点的左边都是它的左子树节点,右边都是它右子树节点。再计算左右子树节点个数,得到左右子树的先序遍历顺序。代码如下
public TreeNode buildTree(int[] preorder, int[] inorder) {
TreeNode root = findRoot(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);
return root;
}
public TreeNode findRoot(int[] preorder, int l, int r, int[] inorder, int ll, int rr) {
if (l > r) {
return null;
}
TreeNode node = new TreeNode(preorder[l]);
for (int i = ll; i <= rr; i++) {
if (inorder[i] == preorder[l]) {
// 中序遍历左边的个数
int left = i - ll;
node.left = findRoot(preorder, l + 1, l + left, inorder, ll, i - 1);
node.right = findRoot(preorder, l + left + 1, r, inorder, i + 1, rr);
}
}
return node;
}
类型2的题目,也是找根节点,根节点即为有序遍历的中点。代码如下
public void flatten(TreeNode root) {
TreeNode pre = new TreeNode(-1);
dfs(pre, root);
}
public TreeNode dfs(TreeNode pre, TreeNode node) {
if (node == null) {
return pre;
}
TreeNode left = node.left;
TreeNode right = node.right;
node.left = null;
pre.right = node;
pre = node;
TreeNode pre1 = dfs(pre, left);
TreeNode pre2 = dfs(pre1, right);
return pre2;
}