解法一:递归

递归判断子树是否同构,直接比较原树或者交换左右子树后再比较。边界条件为遍历到叶子结点。

  1. import java.io.BufferedReader;
  2. import java.io.IOException;
  3. import java.io.InputStreamReader;
  4. class Node {
  5. char val;
  6. Node left;
  7. Node right;
  8. public Node() {
  9. }
  10. }
  11. public class Main {
  12. public static void main(String[] args) throws IOException {
  13. // 读入数据
  14. BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
  15. final int lenA = Integer.parseInt(reader.readLine());
  16. Node rootA = buildTree(reader, lenA);
  17. final int lenB = Integer.parseInt(reader.readLine());
  18. Node rootB = buildTree(reader, lenB);
  19. if (lenA != lenB) {
  20. System.out.println("No");
  21. return;
  22. }
  23. if (dfs(rootA, rootB)) {
  24. System.out.println("Yes");
  25. } else {
  26. System.out.println("No");
  27. }
  28. }
  29. /**
  30. * 建树
  31. *
  32. * @param reader 输入
  33. * @param len 结点数
  34. * @return 树的根结点
  35. * @throws IOException
  36. */
  37. private static Node buildTree(BufferedReader reader, int len) throws IOException {
  38. boolean[] hasFather = new boolean[len];
  39. String[] strs;
  40. char val;
  41. Node left, right;
  42. int number;
  43. Node[] tree = new Node[len];
  44. for (int i = 0; i < len; ++i) {
  45. tree[i] = new Node();
  46. }
  47. for (int i = 0; i < len; ++i) {
  48. strs = reader.readLine().split(" ");
  49. val = strs[0].charAt(0);
  50. if (strs[1].charAt(0) == '-') {
  51. left = null;
  52. } else {
  53. number = Integer.parseInt(strs[1]);
  54. left = tree[number];
  55. hasFather[number] = true;
  56. }
  57. if (strs[2].charAt(0) == '-') {
  58. right = null;
  59. } else {
  60. number = Integer.parseInt(strs[2]);
  61. right = tree[number];
  62. hasFather[number] = true;
  63. }
  64. tree[i].val = val;
  65. tree[i].left = left;
  66. tree[i].right = right;
  67. }
  68. Node root = null;
  69. for (int i = 0; i < len; ++i) {
  70. if (!hasFather[i]) {
  71. root = tree[i];
  72. break;
  73. }
  74. }
  75. return root;
  76. }
  77. private static boolean dfs(Node rootA, Node rootB) {
  78. if (rootA == null && rootB == null) {
  79. return true;
  80. }
  81. if (rootA == null || rootB == null) {
  82. return false;
  83. }
  84. boolean isLeafA = (rootA.left == null) && (rootA.right == null);
  85. boolean isLeafB = (rootB.left == null) && (rootB.right == null);
  86. if (isLeafA && isLeafB) { // 都是叶子结点
  87. return rootA.val == rootB.val;
  88. } else if (isLeafA || isLeafB) { // 其中一个是叶子结点
  89. return false;
  90. } else { // 递归判断子树是否同构
  91. return (dfs(rootA.left, rootB.left) && dfs(rootA.right, rootB.right)) ||
  92. (dfs(rootA.left, rootB.right) && dfs(rootA.right, rootB.left));
  93. }
  94. }
  95. }