gpt4 book ai didi

algorithm - 最低公共(public)祖先实现 - 有什么区别?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:16:31 24 4
gpt4 key购买 nike

我一直在阅读 the Lowest Common Ancestor algorithm on top coder而且我不明白为什么涉及 RMQ 算法 - 那里列出的解决方案非常复杂并且具有以下属性:

  • O(sqrt(n)) 搜索时间复杂度,O(n) 预计算时间复杂度
  • O(n) 空间复杂度用于存储每个节点的父节点
  • 又是O(n)的空间复杂度,用于存储每个节点的预计算

我的解决方案:给定 2 个整数值,通过简单的前序遍历找到节点。取一个节点并沿着树向上移动并将路径存储到一个集合中。取另一个节点并沿着树向上移动,并在我向上移动时检查每个节点:如果该节点在 Set 中,则停止并返回 LCA。 Full implementation .

  • O(n) 时间复杂度,用于查找 2 个节点中的每一个,给定值(因为它是一个常规树,而不是 BST -
  • O(log n) 的空间复杂度,用于将路径存储到 Set 中
  • 从第二个节点上树的时间复杂度为O(log n)

那么给定这两个选择,Top Coder 上的算法是否更好,如果是,为什么?这就是我无法理解的。我认为 O(log n) 比 O(sqrt(n)) 更好。

public class LCA {

private class Node {

int data;
Node[] children = new Node[0];
Node parent;

public Node() {
}

public Node(int v) {
data = v;
}

@Override
public boolean equals(Object other) {
if (this.data == ((Node) other).data) {
return true;
}
return false;
}
}
private Node root;

public LCA() {
root = new Node(3);

root.children = new Node[4];
root.children[0] = new Node(15);
root.children[0].parent = root;
root.children[1] = new Node(40);
root.children[1].parent = root;
root.children[2] = new Node(100);
root.children[2].parent = root;
root.children[3] = new Node(10);
root.children[3].parent = root;

root.children[0].children = new Node[3];
root.children[0].children[0] = new Node(22);
root.children[0].children[0].parent = root.children[0];
root.children[0].children[1] = new Node(11);
root.children[0].children[1].parent = root.children[0];
root.children[0].children[2] = new Node(99);
root.children[0].children[2].parent = root.children[0];

root.children[2].children = new Node[2];
root.children[2].children[0] = new Node(120);
root.children[2].children[0].parent = root.children[2];
root.children[2].children[1] = new Node(33);
root.children[2].children[1].parent = root.children[2];

root.children[3].children = new Node[4];
root.children[3].children[0] = new Node(51);
root.children[3].children[0].parent = root.children[3];
root.children[3].children[1] = new Node(52);
root.children[3].children[1].parent = root.children[3];
root.children[3].children[2] = new Node(53);
root.children[3].children[2].parent = root.children[3];
root.children[3].children[3] = new Node(54);
root.children[3].children[3].parent = root.children[3];

root.children[3].children[0].children = new Node[2];
root.children[3].children[0].children[0] = new Node(25);
root.children[3].children[0].children[0].parent = root.children[3].children[0];
root.children[3].children[0].children[1] = new Node(26);
root.children[3].children[0].children[1].parent = root.children[3].children[0];

root.children[3].children[3].children = new Node[1];
root.children[3].children[3].children[0] = new Node(27);
root.children[3].children[3].children[0].parent = root.children[3].children[3];
}

private Node findNode(Node root, int value) {
if (root == null) {
return null;
}
if (root.data == value) {
return root;
}
for (int i = 0; i < root.children.length; i++) {
Node found = findNode(root.children[i], value);
if (found != null) {
return found;
}
}
return null;
}

public void LCA(int node1, int node2) {
Node n1 = findNode(root, node1);
Node n2 = findNode(root, node2);
Set<Node> ancestors = new HashSet<Node>();
while (n1 != null) {
ancestors.add(n1);
n1 = n1.parent;
}
while (n2 != null) {
if (ancestors.contains(n2)) {
System.out.println("Found common ancestor between " + node1 + " and " + node2 + ": node " + n2.data);
return;
}
n2 = n2.parent;
}
}

public static void main(String[] args) {
LCA tree = new LCA();
tree.LCA(33, 27);
}
}

最佳答案

LCA 算法适用于任何树(不一定是二叉树,也不一定是平衡树)。您的“简单算法”分析失败了,因为跟踪到根节点的路径实际上是 O(N) 时间和空间而不是 O(log N)

关于algorithm - 最低公共(public)祖先实现 - 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7697042/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com