Сегодня в школе учитель попросил нас реализовать алгоритм удаления дубликатов. Это не так сложно, и все придумали следующее решение (псевдокод):
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(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
. Поэтому весь СС n*log(n)
, если не ошибаюсь.
Затем у меня появилась другая идея об использовании бинарного дерева, но я не могу оторваться от нее.
В основном мои вопросы таковы:
- Верен ли мой расчет CC? (а если нет, то почему?)
- Есть ли более быстрый метод для этого?
Спасибо
vS
и что именно делаетadd
? - person Robin Green   schedule 20.05.2011