2012-06-23 1 views
2

Я читал это question. Выбранный ответ содержит следующие два алгоритма. Я не мог понять, почему первая сложность времени - O (ln (n)). В худшем случае, если массив не содержит никаких дубликатов, он будет циклически n раз, а второй. Я ошибаюсь или что-то не хватает? СпасибоПочему следующие два дублирующих алгоритма поиска имеют разную временную сложность?

1) быстрее (в пределе) способ

Вот подход, основанный хэш. Вы должны платить за автобоксинг, но это O (ln (n)) вместо O (n2). Предприимчивый душа бы найти примитивный ИНТ на основе хэш-набор (Apache или Google Collections имеет такую ​​вещь, мне кажется.)

boolean duplicates(final int[] zipcodelist) 
{ 
    Set<Integer> lump = new HashSet<Integer>(); 
    for (int i : zipcodelist) 
    { 
    if (lump.contains(i)) return true; 
    lump.add(i); 
    } 
    return false; 
} 

2) Поклон HuyLe

ответ

знакомства HuyLe для более или менее O (п) решение, которое я думаю, потребности пару из add'l шагов:

static boolean duplicates(final int[] zipcodelist) {  
    final int MAXZIP = 99999;  
    boolean[] bitmap = new boolean[MAXZIP+1];  
    java.util.Arrays.fill(bitmap, false);  

    for (int item : zipcodeList) 
     if (!bitmap[item]) bitmap[item] = true; 
     else return true;  
    } 

    return false; 
} 
+0

Я думаю, что для «более быстрого (предельного) пути» автор опечатал и должен был написать «O (n * log (n))», то есть то, что вы получили от, например. набор, поддерживаемый сбалансированным двоичным деревом поиска. Совершенно очевидно, что не может быть пути быстрее, чем «O (n)». –

+0

Я не получил часть журнала (n). – WowBow

+1

В сбалансированном BST вставка и поиск - 'O (log (size))', поэтому, если вы выполняете 'n' поиск и вставки, вы выполняете операции' O (n * log n) '. Я предполагаю, что здесь выходит журнал. –

ответ

3

Первое решением следовало ожидать сложность O (N), так как весь список почтового индекса должен быть пройден, и обработка каждый почтовый индекс представляет собой O (1) ожидаемую сложность времени.

Даже принимая во внимание, что включение в HashMap может вызвать повторный хэш, сложность по-прежнему O(1). Это немного нелогично, поскольку между Java HashMap и предположением в ссылке не существует никакой связи, но она показывает, что это возможно.

Из HashSet документации:

Этого класс предлагает постоянного время производительности для основных операций (добавить, удалить, содержит и размер), предполагая, что хэш-функция рассеивает элементы должным образом среди ковши.

То же самое для второго решения, которое правильно анализируется: O (n).

(Только примечание не по теме, битСет быстрее, чем массив, как видно в исходном сообщении, поскольку 8 boolean s упакованы в 1 byte, который использует меньше памяти).

+0

i.e оба имеют одинаковую сложность времени, O (n). Правильно? – WowBow

+0

@WowBow: временная сложность такая же (при отсутствии сильного столкновения). – nhahtdh

+0

Их не должно быть, если Хэш используется и выполняется должным образом. Этот ответ не всегда правильный! – trumpetlicks

Смежные вопросы