今天在学校老师要求我们实现一个重复删除算法。没那么难,大家想出了下面的解决方案(伪代码):
for i from 1 to n - 1
for j from i + 1 to n
if v[i] == v[j] then remove(v, v[j]) // remove(from, what)
next j
next i
该算法的计算复杂度为n(n-1)/2
。 (我们在高中,我们还没有谈论过大O,但似乎是O(n^2)
)。这个解决方案看起来很丑陋,当然也很慢,所以我尝试编写更快的代码:
procedure binarySearch(vector, element, *position)
// this procedure searches for element in vector, returning
// true if found, false otherwise. *position will contain the
// element's place (where it is or where it should be)
end procedure
----
// same type as v
vS = new array[n]
for i from 1 to n - 1
if binarySearch(vS, v[i], &p) = true then
remove(v, v[i])
else
add(vS, v[i], p) // adds v[i] in position p of array vS
end if
next i
这边走vS
将包含我们已经传递的所有元素。如果元素v[i]
位于此数组中,则它是重复项并被删除。二分查找的计算复杂度为log(n)
对于主循环(第二个片段)是n
。因此整个CC是n*log(n)
如果我没错的话。
然后我又想到了使用二叉树,但又爱不释手。
基本上我的问题是:
- 我的CC计算正确吗? (如果不是,为什么?)
- 有没有更快的方法?
Thanks