1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
| public class LowestAncestor {
public static Node lowestAncestor1(Node head, Node o1, Node o2) { if (head == null) { return null; } HashMap<Node, Node> parentMap = new HashMap<>(); parentMap.put(head, null); fillParentMap(head, parentMap); HashSet<Node> o1Set = new HashSet<>(); Node cur = o1; o1Set.add(cur); while (parentMap.get(cur) != null) { cur = parentMap.get(cur); o1Set.add(cur); } cur = o2; while (!o1Set.contains(cur)) { cur = parentMap.get(cur); } return cur; }
public static void fillParentMap(Node head, HashMap<Node, Node> parentMap) { if (head.left != null) { parentMap.put(head.left, head); fillParentMap(head.left, parentMap); } if (head.right != null) { parentMap.put(head.right, head); fillParentMap(head.right, parentMap); } }
public static Node lowestAncestor2(Node head, Node o1, Node o2) { return process(head, o1, o2).ans; }
public static class Info { public Node ans; public boolean findO1; public boolean findO2;
public Info(Node a, boolean f1, boolean f2) { ans = a; findO1 = f1; findO2 = f2; } }
public static Info process(Node head, Node o1, Node o2) { if (head == null) { return new Info(null, false, false); } Info leftInfo = process(head.left, o1, o2); Info rightInfo = process(head.right, o1, o2);
boolean findO1 = head == o1 || leftInfo.findO1 || rightInfo.findO1; boolean findO2 = head == o2 || leftInfo.findO2 || rightInfo.findO2; Node ans = null; if (leftInfo.ans != null) { ans = leftInfo.ans; } if (rightInfo.ans != null) { ans = rightInfo.ans; } if (ans == null) { if (findO1 && findO2) { ans = head; } } return new Info(ans, findO1, findO2); }
public static void main(String[] args) { int maxLevel = 4; int maxValue = 100; int testTimes = 1000000; for (int i = 0; i < testTimes; i++) { Node head = generateRandomBST(maxLevel, maxValue); Node o1 = pickRandomOne(head); Node o2 = pickRandomOne(head); if (lowestAncestor1(head, o1, o2) != lowestAncestor2(head, o1, o2)) { System.out.println("Oops!"); } } System.out.println("finish!"); }
public static class Node { public int value; public Node left; public Node right;
public Node(int data) { this.value = data; } }
public static Node generateRandomBST(int maxLevel, int maxValue) { return generate(1, maxLevel, maxValue); }
public static Node generate(int level, int maxLevel, int maxValue) { if (level > maxLevel || Math.random() < 0.5) { return null; } Node head = new Node((int) (Math.random() * maxValue)); head.left = generate(level + 1, maxLevel, maxValue); head.right = generate(level + 1, maxLevel, maxValue); return head; }
public static Node pickRandomOne(Node head) { if (head == null) { return null; } ArrayList<Node> arr = new ArrayList<>(); fillPrelist(head, arr); int randomIndex = (int) (Math.random() * arr.size()); return arr.get(randomIndex); }
public static void fillPrelist(Node head, ArrayList<Node> arr) { if (head == null) { return; } arr.add(head); fillPrelist(head.left, arr); fillPrelist(head.right, arr); } }
|