找到在二叉树中给出两个值的最不常见的祖先

时间:2012-10-27 23:25:16

标签: algorithm binary-tree ancestor

我在编程面试中得到了这个问题。随意考虑如何回答它。

您获得了二叉树(不是二叉搜索树)的根节点,其中每个节点都包含一个整数值,并且没有值出现两次。您还会获得两个值val1val2(可能在树中也可能不在树中。)如果两者都在树中,则返回两个节点中最不常见的祖先节点包含这两个值。如果没有,则返回null。

假设每个节点都可以访问左右子节点。您可以附加节点结构,但可以将父节点附加到每个节点。您的算法应该小于O(N ^ 2),其中N是树中节点的数量。

注意:虽然它与着名的最小共同祖先问题类似,但这个问题的局限性并不完全相同。

1 个答案:

答案 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);
}

我想一些解释是有道理的,但也许因为它只是一个脑筋急转弯,所以最好把那些代码放在那里,看看人们对它做了些什么。 (我还没有彻底测试过,让它看起来更像是一次采访。)

这不是我在采访中曾经使用的问题,而且我不确定如果有人提出上述代码作为答案我会做些什么。但后来我一直都不确定自己会雇用自己。