我在编程面试中得到了这个问题。随意考虑如何回答它。
您获得了二叉树(不是二叉搜索树)的根节点,其中每个节点都包含一个整数值,并且没有值出现两次。您还会获得两个值val1
和val2
(可能在树中也可能不在树中。)如果两者都在树中,则返回两个节点中最不常见的祖先节点包含这两个值。如果没有,则返回null。
假设每个节点都可以访问左右子节点。您可以附加节点结构,但可以不将父节点附加到每个节点。您的算法应该小于O(N ^ 2),其中N是树中节点的数量。
注意:虽然它与着名的最小共同祖先问题类似,但这个问题的局限性并不完全相同。
答案 0 :(得分:0)
我不明白为什么你会考虑O(N 2 ),除非我误解了这个问题。以下解决方案是前序遍历,因此最多访问每个节点一次:
struct node* visit(struct node* visited, int p, int q, struct node* sentinel) {
if (!visited) return visited;
if (visited->data == p || visited->data == q) {
struct node* t;
if ((t = visit(visited->left, p, q, visited))) return t;
if ((t = visit(visited->right, p, q, visited))) return t;
return sentinel;
} else {
struct node* left = visit(visited->left, p, q, visited);
struct node* right = visit(visited->right, p, q, visited);
if (left == visited) return right ? right : sentinel;
if (right == visited) return left ? left : sentinel;
return left ? left : right;
}
}
struct node* lca(struct node* root, int val1, int val2) {
return visit(root, val1, val2, 0);
}
我想一些解释是有道理的,但也许因为它只是一个脑筋急转弯,所以最好把那些代码放在那里,看看人们对它做了些什么。 (我还没有彻底测试过,让它看起来更像是一次采访。)
这不是我在采访中曾经使用的问题,而且我不确定如果有人提出上述代码作为答案我会做些什么。但后来我一直都不确定自己会雇用自己。