import java.util.*;
import java.lang.*;
import java.io.*;
class Ideone {
static class Node {
List<Node> children = new ArrayList<Node>();
this.id = id;
}
return id.toString();
}
}
//test data
Node root = new Node(0);
Node n1 = new Node(1);
Node n2 = new Node(2);
Node n3 = new Node(3);
Node n1a = new Node(11);
Node n1b = new Node(12);
Node n3a = new Node(31);
Node n3b = new Node(32);
Node n3c = new Node(33);
//connections
root.children.add(n1);
root.children.add(n2);
root.children.add(n3);
n1.children.add(n1a);
n1.children.add(n1b);
n3.children.add(n3a);
n3.children.add(n3b);
n3.children.add(n3c);
//tests
System.
out.
println("### Test 1 ###"); Node r = findClosestCommonAncestor(root, n1b, n3a);
System.
out.
println("Expected: " + root
); System.
out.
println("Result: " + r
); System.
out.
println("Passed --> " + (r
== root
));
System.
out.
println("### Test 2 ###"); r = findClosestCommonAncestor(root, n3, n3b);
System.
out.
println("Expected: " + n3
); System.
out.
println("Result: " + r
); System.
out.
println("Passed --> " + (r
== n3
));
System.
out.
println("### Test 3 ###"); r = findClosestCommonAncestor(root, n3a, n3c);
System.
out.
println("Expected: " + n3
); System.
out.
println("Result: " + r
); System.
out.
println("Passed --> " + (r
== n3
));
System.
out.
println("### Test 4 ###"); r = findClosestCommonAncestor(root, n2, n1a);
System.
out.
println("Expected: " + root
); System.
out.
println("Result: " + r
); System.
out.
println("Passed --> " + (r
== root
)); }
static Node findClosestCommonAncestor(Node root, Node p, Node q) {
if (root == null) {
return null;
}
if(root == p || root == q) {
return root;
} else {
Node aux = null;
//if two children contains p and q, root is the ancestor
for (Node current : root.children) {
Node child = findClosestCommonAncestor(current, p, q);
if (child != null) {
if (aux == null) {
aux = child;
} else {
return root;
}
}
}
if (aux != null) return aux;
}
return null;
}
}
aW1wb3J0IGphdmEudXRpbC4qOwppbXBvcnQgamF2YS5sYW5nLio7CmltcG9ydCBqYXZhLmlvLio7CgpjbGFzcyBJZGVvbmUgewoJCglzdGF0aWMgY2xhc3MgTm9kZSB7CgkJTGlzdDxOb2RlPiBjaGlsZHJlbiA9IG5ldyBBcnJheUxpc3Q8Tm9kZT4oKTsKCQlJbnRlZ2VyIGlkOwoJCU5vZGUoSW50ZWdlciBpZCkgewoJCQl0aGlzLmlkID0gaWQ7CgkJfQoJCXB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CgkJCXJldHVybiBpZC50b1N0cmluZygpOwoJCX0KCX0KCQoJcHVibGljIHN0YXRpYyB2b2lkIG1haW4gKFN0cmluZ1tdIGFyZ3MpIHRocm93cyBqYXZhLmxhbmcuRXhjZXB0aW9uIHsKCQkKCQkvL3Rlc3QgZGF0YQoJCU5vZGUgcm9vdCA9IG5ldyBOb2RlKDApOwoJCU5vZGUgbjEgPSBuZXcgTm9kZSgxKTsKCQlOb2RlIG4yID0gbmV3IE5vZGUoMik7CgkJTm9kZSBuMyA9IG5ldyBOb2RlKDMpOwoJCU5vZGUgbjFhID0gbmV3IE5vZGUoMTEpOwoJCU5vZGUgbjFiID0gbmV3IE5vZGUoMTIpOwoJCU5vZGUgbjNhID0gbmV3IE5vZGUoMzEpOwoJCU5vZGUgbjNiID0gbmV3IE5vZGUoMzIpOwoJCU5vZGUgbjNjID0gbmV3IE5vZGUoMzMpOwoJCQoJCS8vY29ubmVjdGlvbnMKCQlyb290LmNoaWxkcmVuLmFkZChuMSk7CgkJcm9vdC5jaGlsZHJlbi5hZGQobjIpOwoJCXJvb3QuY2hpbGRyZW4uYWRkKG4zKTsKCQluMS5jaGlsZHJlbi5hZGQobjFhKTsKCQluMS5jaGlsZHJlbi5hZGQobjFiKTsKCQluMy5jaGlsZHJlbi5hZGQobjNhKTsKCQluMy5jaGlsZHJlbi5hZGQobjNiKTsKCQluMy5jaGlsZHJlbi5hZGQobjNjKTsKCQkKCQkvL3Rlc3RzCgkJU3lzdGVtLm91dC5wcmludGxuKCIjIyMgVGVzdCAxICMjIyIpOwoJCU5vZGUgciA9IGZpbmRDbG9zZXN0Q29tbW9uQW5jZXN0b3Iocm9vdCwgbjFiLCBuM2EpOwoJCVN5c3RlbS5vdXQucHJpbnRsbigiRXhwZWN0ZWQ6ICIgKyByb290KTsKCQlTeXN0ZW0ub3V0LnByaW50bG4oIlJlc3VsdDogIiArIHIpOwoJCVN5c3RlbS5vdXQucHJpbnRsbigiUGFzc2VkIC0tPiAiICsgKHIgPT0gcm9vdCkpOwoJCQoJCVN5c3RlbS5vdXQucHJpbnRsbigiIyMjIFRlc3QgMiAjIyMiKTsKCQlyID0gZmluZENsb3Nlc3RDb21tb25BbmNlc3Rvcihyb290LCBuMywgbjNiKTsKCQlTeXN0ZW0ub3V0LnByaW50bG4oIkV4cGVjdGVkOiAiICsgbjMpOwoJCVN5c3RlbS5vdXQucHJpbnRsbigiUmVzdWx0OiAiICsgcik7CgkJU3lzdGVtLm91dC5wcmludGxuKCJQYXNzZWQgLS0+ICIgKyAociA9PSBuMykpOwoJCQoJCVN5c3RlbS5vdXQucHJpbnRsbigiIyMjIFRlc3QgMyAjIyMiKTsKCQlyID0gZmluZENsb3Nlc3RDb21tb25BbmNlc3Rvcihyb290LCBuM2EsIG4zYyk7CgkJU3lzdGVtLm91dC5wcmludGxuKCJFeHBlY3RlZDogIiArIG4zKTsKCQlTeXN0ZW0ub3V0LnByaW50bG4oIlJlc3VsdDogIiArIHIpOwoJCVN5c3RlbS5vdXQucHJpbnRsbigiUGFzc2VkIC0tPiAiICsgKHIgPT0gbjMpKTsKCQkKCQlTeXN0ZW0ub3V0LnByaW50bG4oIiMjIyBUZXN0IDQgIyMjIik7CgkJciA9IGZpbmRDbG9zZXN0Q29tbW9uQW5jZXN0b3Iocm9vdCwgbjIsIG4xYSk7CgkJU3lzdGVtLm91dC5wcmludGxuKCJFeHBlY3RlZDogIiArIHJvb3QpOwoJCVN5c3RlbS5vdXQucHJpbnRsbigiUmVzdWx0OiAiICsgcik7CgkJU3lzdGVtLm91dC5wcmludGxuKCJQYXNzZWQgLS0+ICIgKyAociA9PSByb290KSk7Cgl9CgkKCXN0YXRpYyBOb2RlIGZpbmRDbG9zZXN0Q29tbW9uQW5jZXN0b3IoTm9kZSByb290LCBOb2RlIHAsIE5vZGUgcSkgewoJCQogICAgICAgIGlmIChyb290ID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICBpZihyb290ID09IHAgfHwgcm9vdCA9PSBxKSB7CiAgICAgICAgCQogICAgICAgICAgICByZXR1cm4gcm9vdDsKICAgICAgICAgICAgCiAgICAgICAgfSBlbHNlIHsKCgkJCU5vZGUgYXV4ID0gbnVsbDsKCgkJCS8vaWYgdHdvIGNoaWxkcmVuIGNvbnRhaW5zIHAgYW5kIHEsIHJvb3QgaXMgdGhlIGFuY2VzdG9yCgkJCWZvciAoTm9kZSBjdXJyZW50IDogcm9vdC5jaGlsZHJlbikgewoJCQkJCgkJCQlOb2RlIGNoaWxkID0gZmluZENsb3Nlc3RDb21tb25BbmNlc3RvcihjdXJyZW50LCBwLCBxKTsKCQkJCWlmIChjaGlsZCAhPSBudWxsKSB7CgkJCQkJaWYgKGF1eCA9PSBudWxsKSB7CgkJCQkJCWF1eCA9IGNoaWxkOwoJCQkJCX0gZWxzZSB7CgkJCQkJCXJldHVybiByb290OwoJCQkJCX0KCQkJCX0KCQkJCQoJCQl9CgkJCWlmIChhdXggIT0gbnVsbCkgcmV0dXJuIGF1eDsKCiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiBudWxsOwoJfQoKfQ==