当前位置:  首页>> 技术小册>> 数据结构与算法(下)

题目描述

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列 {1,2,4,7,3,5,6,8} 和中序遍历序列 {4,7,2,1,5,3,8,6},则重建二叉树并返回。

解法

在二叉树的前序遍历序列中,第一个数字总是根结点的值。在中序遍历序列中,根结点的值在序列的中间,左子树的结点位于根结点左侧,而右子树的结点位于根结点值的右侧。

遍历中序序列,找到根结点,递归构建左子树与右子树。

注意添加特殊情况的 if 判断。

  1. /**
  2. * Definition for binary tree
  3. * public class TreeNode {
  4. * int val;
  5. * TreeNode left;
  6. * TreeNode right;
  7. * TreeNode(int x) { val = x; }
  8. * }
  9. */
  10. /**
  11. * @author bingo
  12. * @since 2018/10/28
  13. */
  14. public class Solution {
  15. /**
  16. * 重建二叉树
  17. *
  18. * @param pre 先序序列
  19. * @param in 中序序列
  20. * @return 二叉树根结点
  21. */
  22. public TreeNode reConstructBinaryTree(int[] pre, int[] in) {
  23. if (pre == null || in == null || pre.length != in.length) {
  24. return null;
  25. }
  26. int n = pre.length;
  27. return constructBinaryTree(pre, 0, n - 1, in, 0, n - 1);
  28. }
  29. private TreeNode constructBinaryTree(int[] pre, int startPre, int endPre, int[] in, int startIn, int endIn) {
  30. TreeNode node = new TreeNode(pre[startPre]);
  31. if (startPre == endPre) {
  32. if (startIn == endIn) {
  33. return node;
  34. }
  35. throw new IllegalArgumentException("Invalid input!");
  36. }
  37. int inOrder = startIn;
  38. while (in[inOrder] != pre[startPre]) {
  39. ++inOrder;
  40. if (inOrder > endIn) {
  41. new IllegalArgumentException("Invalid input!");
  42. }
  43. }
  44. int len = inOrder - startIn;
  45. if (len > 0) {
  46. // 递归构建左子树
  47. node.left = constructBinaryTree(pre, startPre + 1, startPre + len, in, startIn, inOrder - 1);
  48. }
  49. if (inOrder < endIn) {
  50. // 递归构建右子树
  51. node.right = constructBinaryTree(pre, startPre + len + 1, endPre, in, inOrder + 1, endIn);
  52. }
  53. return node;
  54. }
  55. }

测试用例

  1. 普通二叉树(完全二叉树;不完全二叉树);
  2. 特殊二叉树(所有结点都没有左/右子结点;只有一个结点的二叉树);
  3. 特殊输入测试(二叉树根结点为空;输入的前序序列和中序序列不匹配)。

该分类下的相关小册推荐: