【问题标题】:For k collections all of which have length = N, finding common elements with a O((k-1)*N)对于所有长度 = N 的 k 个集合,找到具有 O((k-1)*N) 的公共元素
【发布时间】:2018-02-20 04:36:40
【问题描述】:

我应该编写一个代码,它应该有效地找到存在于 k 个 N 元素集合中的公共元素。所有的集合都是排序的,它们可能有不同的大小,但为了简单起见,我们假设大小相同。唯一重要的是元素之间的比较;应该小于 O((k-1)*N)。

我已经开发了下面的代码,但在提到的情况下,比较次数约为 (k-1)NN

提前感谢帮助。

//Arrays are sorted and the shortest array is chosen as the query automatically    
boolean com;
loop1: for (int i = 0; i < QuetyList.length; ++i) { 
    com = false;
    loop2: for (int k = 0; k < OtherLists.length; ++k) {
        com = false;
        loop3: for (int y = 0; y < OtherLists[k].size(); ++y) {
            ++comparisons;
            if (QueryList[i].compareTo(OtherLists[k][y]) == 0) {
                com = true;
                break loop3;
            }
            ++comparisons;
            if (QueryList[i].compareTo(OtherLists[k][y]) < 0) {
                break;
            }        
        }
        if (com == false) {
            break;
        }
    }
    if (com == true) {
        commons.add(QueryList[i]);
    }
}   

样本测试

Comparable [] QuetyList = {200,200,200,200};
Comparable [] collection2 = {2,10,50,200};
Comparable [] collection3 = {2,10,40,200};
Comparable [][] OtherLists = {collection2,collection3};

这是作业。您有可能在教育的某个时间跨过。提前致谢。

【问题讨论】:

  • 它们是可散列的吗?你能把记忆扔给它吗?你能遍历每个列表中的所有元素,存储在一个 HashMap 中,其中 value 是一个位域,指定哪些列表包含键?如果是这样,您实际上并不需要对元素进行排序。否则,简化问题。首先求解 k=2。然后尝试扩展。

标签: java sorting sos


【解决方案1】:

基本思想是在你拥有的每个列表上保留一个索引,并且只有在索引处的值是所有列表中最小的时候才推进这个索引。

我看不出它是否可以同时处理 k 个列表,但肯定可以一次处理 2 个列表,每个列表都应该进行 N 次比较,这应该会给你O(k * N)(k-1 次 N 比较)。

类似:

public Comparable[] common(Comparable[] a, Comparable[] b) {
    // List is more flexible, but the toArray at the end is a bit costly. You can probably figure a better way of doing this.
    List<Comparable> res = new ArrayList<>();
    int indexA = 0;
    int indexB = 0;
    while (indexA < a.length && indexB < b.length) {
        // Exercice for the reader: replace with compareTo calls
        if (a[indexA] == b[indexB]) {
            // Common item!
            res.add(a[indexA]);
            indexA++;
            indexB++;
        } else if (a[indexA] < b[indexB]) {
            // item in A is smaller, try the next
            indexA++;
        } else {
            indexB++;
        }
    }
    return res.toArray(new Comparable[0]);
}

据此,您可以将列表 2 到 2 分组,直到只剩下一个列表。

【讨论】:

  • 不是O(log(k)*N)。您必须合并所有子列表,所以除非我遗漏了什么,否则就是 (k-1) 次运行您的函数。
  • @MFisherKDX 你说得对,这个时间我数不过来 :)
猜你喜欢
  • 1970-01-01
  • 2020-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-01
  • 1970-01-01
相关资源
最近更新 更多