【问题标题】:Checking duplicates in an array, and removing them is worst-case complexity O(n^2) or O(n^3)?检查数组中的重复项并删除它们是最坏情况复杂度 O(n^2) 还是 O(n^3)?
【发布时间】:2016-02-13 02:55:44
【问题描述】:

我正在尝试评估这个算法:

  • 检查相等性是 O(n2)

  • 移除一个元素是 O(n)

所以我认为整个算法在最坏的情况下会是 O(n^3)。

    for (i = 0; i < ne-1; i++)
    {
        for (j = i+1; j < ne; j++)
        {
            if (strcmp(array[i].id, array[j].id)==0)
            {
                cont++;   

                for (k = j; k < ne - 1; k++)  
                    array[k] = array[k + 1];
                ne--;   
            }
        }
    }

【问题讨论】:

  • 这是有效的 C 代码吗?
  • 是的,array 是一个包含 3 个 char[20] 类型字段的结构
  • 能否将您当前的代码替换为MCVE?例如,我看不到你的任何变量是在哪里声明的。
  • @Elogent 这不是与实际问题无关吗?
  • 重写代码以显示最坏的情况,并自己看看。很难理解你不知道什么以及你在哪里估计有问题。在变量名上保存字节也使得理解代码的意图非常痛苦。

标签: c algorithm duplicates time-complexity


【解决方案1】:

虽然你说比较的成本是 O(n2) 并且删除一个元素的成本是 O(n) 是正确的,但是这两个动作之间的相互关系导致整个算法为 O(n2)。由于O(n2)在O(n3)中,所以说算法是O(n3)也不对,但这不是一个严格的界限。

要了解原因,请考虑数组中某些元素的成本。它将与每个后续元素进行比较(如array[i]),或者将其删除,涉及所有后续元素的移位。但不是两者兼而有之;一旦被移除,它就永远不会是外循环中使用的元素。

无论哪种情况,元素的代价都是后面的元素个数,算法的总代价是最坏情况n(n-1)/2,也就是O(n2支持>)。 (如果元素被删除,实际成本会更少;如果没有重复,最坏的情况会发生。)

正如@Amit 所指出的,如果执行比较或移动的成本不是 O(1),则必须考虑这一点,导致 O(n2 m) 其中m 是比较或分配的成本。但认为固定成本是正常的。

正如我在评论中指出的,所提供的算法是不正确的。正确的算法是:

for (i = 0; i < n - 1; ++i) {
    for (j = i + 1; j < n; ) {
        if (IsEqual(a[i], a[j])) {
            for (k = j; k < n - 1; ++k)  
                a[k] = a[k + 1];
            --n;   
        } else {
            ++j;
        }
    }
}

通常,更好的解决方案是对数组进行排序,这意味着相等的元素将相邻,然后进行一次 O(n) 传递以压缩结果;那是 O(n log n) (来自排序)但不保留顺序。 (不过,您可以使用辅助数组来保持顺序。)

【讨论】:

  • 感谢您的回复,无论如何我在想一个更好的实现来查找重复项。你认为有可能实现哈希表吗?如果可以的话,我可以做 O(1) 的复杂度。如果我错了,请纠正我。
  • @user3289840:哈希表很好。它是 O(n),而不是 O(1),因为您需要处理所有 n 个元素。更好的说法是,O(1) 平均
  • 使用哈希表,如何处理冲突?可能是重复或碰撞,这可能吗?
  • @user3289840:每个哈希表都有一些处理冲突的机制。看Wikipedia
【解决方案2】:

实际上是 O(n3 m) 其中 mid 字符串的长度(或平均长度id 字符串)。

ith 部分是 O(n)j 也是。您比较每次迭代的 m 个字符,然后 k 是另一个 O(n)。尽管k 的每次迭代都会减少n,因此有可能表明摊销复杂度较低,但这需要更深入的分析。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-13
    • 1970-01-01
    • 2020-06-20
    • 1970-01-01
    • 2018-02-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多