我正在尝试评估此算法:
检查等式是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>';
答案 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 ,但可能会显示摊销的复杂性较低,但这需要更深入的分析。