题目详情

红黑树是自平衡二叉查找树,具有一下性质:红黑树的根节点是黑色;红节点的子节点是黑的;从任何一个节点A出发,到后代叶子节点的所有路径拥有相同的黑节点数。

要求判断所给的前序遍历序列是否是红黑树。

我的版本

首先需要根据红黑树的性质还原红黑树,我用的是递归;

创建好红黑树之后,需要判断(1)相邻节点是否全为红节点、(2)路径黑节点数是否一致。对于(1),直接判断即可;对于(2),类似于动态规划的思想,从叶子节点判断起,使用递归实现状态转移。

  1. import java.util.*;
  2. public class Main {
  3. static int n;
  4. public static void main(String[] args) {
  5. Scanner sc = new Scanner(System.in);
  6. int k = sc.nextInt();
  7. while (k-- > 0) {
  8. n = sc.nextInt();
  9. int[] pre = new int[n];
  10. for (int i = 0; i < n; i ++) {
  11. pre[i] = sc.nextInt();
  12. }
  13. if (pre[0] < 0) {
  14. System.out.println("No");
  15. } else {
  16. node root = create(pre, 0, n);
  17. int bool = judge(root);
  18. if (bool == -1) {
  19. System.out.println("No");
  20. } else {
  21. System.out.println("Yes");
  22. }
  23. }
  24. }
  25. }
  26. static int judge(node root) {
  27. int l = 0, r = 0;
  28. if (root.left != null) {
  29. if (root.value < 0 && root.left.value < 0) return -1; // 相邻节点不能全为红
  30. l = judge(root.left);
  31. }
  32. if (root.right != null) {
  33. if (root.value < 0 && root.right.value < 0) return -1; // 相邻节点不能全为红
  34. r = judge(root.right);
  35. }
  36. if (l >= 0 && l == r) {
  37. if (root.value > 0) return l + 1;
  38. else return l;
  39. }
  40. return -1;
  41. }
  42. static node create(int[] pre, int begin, int end) {
  43. if (begin == end)
  44. return null;
  45. node root = new node(pre[begin]);
  46. int i = begin+1;
  47. for (i = begin+1; i < end; i ++) {
  48. if (Math.abs(pre[i]) > Math.abs(pre[begin])) break;
  49. }
  50. root.left = create(pre, begin+1, i);
  51. root.right = create(pre, i, end);
  52. return root;
  53. }
  54. static class node {
  55. int value;
  56. node left;
  57. node right;
  58. public node(int val) {
  59. this.value = val;
  60. }
  61. }
  62. }