检查数组中的重复项并删除它们是最坏情况下的复杂度O(n ^ 2)还是O(n ^ 3)?

时间:2016-02-13 02:55:44

标签: c algorithm duplicates time-complexity

我正在尝试评估此算法:

  • 检查等式是O(n 2

  • 删除元素是O(n)

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

$button .= '<input type="text" id="parspalpaiddownloads_email_'.$button_id.'" style="font-family: tahoma, verdana; font-size: 14px; line-height: 14px; margin: 5px 0px; padding: 3px 5px; background: #FFF; border: 1px solid #888; width: 200px; -webkit-border-radius: 3px; border-radius: 3px; color: #666; min-height:28px" value="'.esc_attr(__('Email', 'parspalpaiddownloads')).'" onfocus="if (this.value == \''.esc_attr(__('Email', 'parspalpaiddownloads')).'\'){this.value =\'\'; this.style.textAlign= \'left\'; this.style.direction= \'ltr\' }" onblur="if (this.value == \'\') {this.value = \''.esc_attr(__('Email', 'parspalpaiddownloads')).'\';  this.style.textAlign= \'right\'; this.style.direction= \'rtl\'}" /></div>';

2 个答案:

答案 0 :(得分:2)

虽然比较的成本是O(n 2 )并且删除元素的成本是O(n)是正确的,但是两个动作之间的相互关系导致整个算法为O(n 2 )。由于O(n 2 )在O(n 3 )中,因此算法为O(n 3 )并不正确,但这不是一个紧张的约束。

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

在任何一种情况下,元素的成本是以下元素的数量,算法的总成本是最坏情况n(n-1)/ 2,即O(n 2 )。 (如果删除元素,实际成本会更低;如果没有重复,则会出现最坏情况。)

正如@Amit指出的那样,如果执行比较或移动的成本不是O(1),则必须考虑这一点,从而导致O(n 2 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)(来自排序)但不保留顺序。 (不过,您可以使用辅助数组保留顺序。)

答案 1 :(得分:0)

实际上它是 O(n 3 m)其中 m id字符串的长度(或者id字符串的平均长度。

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