Algorithm 使用字典优化O(n^2)算法,是否有可能更进一步

Algorithm 使用字典优化O(n^2)算法,是否有可能更进一步,algorithm,language-agnostic,Algorithm,Language Agnostic,共有2套: 值集1(包含所有可能的值) 值的集合2(包含集合1中的一些可能值) 对于每一场比赛,我们将在第1组中指出我们找到了它 排序的O(n^2)方式是: foreach(var set1Variable in set1) { foreach(var set2Variable in set2) { if(set1Variable == set2Variable ) set1.indexOf(set1Variable).Found = true;

共有2套:

值集1(包含所有可能的值) 值的集合2(包含集合1中的一些可能值)

对于每一场比赛,我们将在第1组中指出我们找到了它

排序的O(n^2)方式是:

foreach(var set1Variable in set1) {
    foreach(var set2Variable in set2) {
        if(set1Variable == set2Variable )
            set1.indexOf(set1Variable).Found = true;
    }
}
它可以通过字典进行优化

第一个解决方案是“好”还是“坏”。那字典呢?我们应该考虑什么? 通过这种方式进行排序的最佳方式是什么?为什么?

  • 建议的解决方案是
    O(n^2)
    time,没有额外的空间
  • 字典解决方案(其中最小集合的所有元素 放置在字典中)可以是
    O(n)
    /
    O(nlogn)
    (取决于 哪个字典,基于树或哈希)时间和
    O(n)
    空间
  • 您还可以通过排序获得
    O(nlogn)
    时间和无额外空间 然后并行迭代以查找匹配项 项目
哪个更好

取决于具体的需要和限制。如果您负担不起额外的空间,那么字典解决方案将变得不可行。如果
O(nlogn)
时间太长,应该坚持使用哈希


附录:解决方案3(排序)伪代码:

sort(set1)
sort(set2)

iter1 = set1.iterator()
iter2 = set2.iterator()
while iter1.has_next() and iter2.has_next():
  if iter1.item() == iter2.item():
    set2.add(iter1.item())
    iter1.next()
    iter2.next()
  else if iter1.item() < iter2.item():
    iter1.next()
  else:
    iter2.next()
排序(set1)
排序(set2)
iter1=set1.iterator()
iter2=set2.iterator()
而iter1.has_next()和iter2.has_next():
如果iter1.item()==iter2.item():
set2.add(iter1.item())
iter1.next()
iter2.next()
否则,如果iter1.item()
  • 建议的解决方案是
    O(n^2)
    time,没有额外的空间
  • 字典解决方案(其中最小集合的所有元素 放置在字典中)可以是
    O(n)
    /
    O(nlogn)
    (取决于 哪个字典,基于树或哈希)时间和
    O(n)
    空间
  • 您还可以通过排序获得
    O(nlogn)
    时间和无额外空间 然后并行迭代以查找匹配项 项目
哪个更好

取决于具体的需要和限制。如果您负担不起额外的空间,那么字典解决方案将变得不可行。如果
O(nlogn)
时间太长,应该坚持使用哈希


附录:解决方案3(排序)伪代码:

sort(set1)
sort(set2)

iter1 = set1.iterator()
iter2 = set2.iterator()
while iter1.has_next() and iter2.has_next():
  if iter1.item() == iter2.item():
    set2.add(iter1.item())
    iter1.next()
    iter2.next()
  else if iter1.item() < iter2.item():
    iter1.next()
  else:
    iter2.next()
排序(set1)
排序(set2)
iter1=set1.iterator()
iter2=set2.iterator()
而iter1.has_next()和iter2.has_next():
如果iter1.item()==iter2.item():
set2.add(iter1.item())
iter1.next()
iter2.next()
否则,如果iter1.item()
您可以创建树集并向其中添加所有集

TreeSet myTreeSet = new TreeSet();
myTreeSet.addAll(myHashSet);
System.out.println(myTreeSet);

假设集合大小为n,空间复杂度为O(n),时间复杂度为O(nlogn)

您可以创建树集并将所有集合添加到树集中

TreeSet myTreeSet = new TreeSet();
myTreeSet.addAll(myHashSet);
System.out.println(myTreeSet);

假设集合的大小为n,空间复杂度为O(n),时间复杂度为O(nlogn)

目标似乎是找到两个集合的交集-为什么要将其标记为
排序
?集合使用的是什么数据结构?如果将set1放入哈希表,并在set2上迭代,检查set1中是否存在每个元素,则可以得到O(n)。如果set 1包含所有可能的值,那么set 3不是与set 2完全相同吗?@HeapOverflow谢谢,你是对的,关于创建第三个集合的初始逻辑有些问题。现在我来编辑question@kaya3因为潜在的解决方案肯定会包括排序,这在一些回答中已经很明显了。目标似乎是找到两个集合的交集-为什么这是标记的
排序
?集合使用的是什么数据结构?如果将set1放入哈希表,并在set2上迭代,检查set1中是否存在每个元素,则可以得到O(n)。如果set 1包含所有可能的值,那么set 3不是与set 2完全相同吗?@HeapOverflow谢谢,你是对的,关于创建第三个集合的初始逻辑有些问题。现在我来编辑question@kaya3因为潜在的解决方案肯定会包括排序,这在一些回答中已经很明显了。这些其他解决方案大概需要多少额外的空间?第一个解决方案被认为是“坏”的,因为它是O(n^2)?即使它占用更少的空间?如果集合中有100个变量呢?@apaki答案中已经提到了这一点。O(n)对于字典,几乎没有额外的排序空间。是的,显然字典解决方案几乎没有额外的空间,而且速度更快。不过,O(n^2)被认为是“坏”的吗?如果你看到有人使用他们的代码中的第一个解决方案,那么这些解决方案需要什么额外的空间,你会考虑多少?第一个解决方案被认为是“坏”的,因为它是O(n^2)?即使它占用更少的空间?如果集合中有100个变量呢?@apaki答案中已经提到了这一点。O(n)对于字典,几乎没有额外的排序空间。是的,显然字典解决方案几乎没有额外的空间,而且速度更快。不过,O(n^2)被认为是“坏”的吗?如果你看到某人在他们的代码中使用第一个解决方案,你会考虑多少?