Сортировка элементов списка в O (logN)

1

Предположим, что у меня есть отсортированный список/массив. Мне нужно подсчитать количество отдельных чисел в этом списке/массиве в повторениях O (logN), которые я уже знаю, что мне нужно использовать какой-то бинарный алгоритм, но я не могу этого сделать в O (logN) повторения в худшем случае. Есть ли идея?

  • 1
    Что значит «посчитать число отличного числа»? Вы хотите знать, сколько существует уникальных номеров? Учитывая число n вы хотите знать, сколько раз это встречается в списке? Список отсортирован? Первая проблема не может быть решена в O (log n), просто имея упорядоченный список. Последнее, если список упорядочен, вы можете просто использовать два варианта бинарного поиска, который дает вам первый индекс i и последний индекс j где этот элемент найден, и у вас есть ji - число вхождений.
  • 1
    В худшем случае все элементы различны, должно быть O (N).
Показать ещё 1 комментарий
Теги:
python-3.x
algorithm
count
time-complexity

2 ответа

1

Используйте модуль bisect.

import bisect as b


arr = [1, 1, 1, 2, 2, 3, 3, 3, 3]
for x in [1, 2, 3, 0]:
    print(b.bisect_right(arr, x) - b.bisect_left(arr, x))

Выход:

3
2
4
0

Таким образом, алгоритм работает для любого значения, которое вы передаете ему. Если переданное значение отсутствует в списке, возвращается 0.


Модуль bisect работает, используя двоичный поиск, чтобы найти подходящее место для вставки данного элемента. bisect_left дает самый левый индекс, а bisect_right дает индекс справа от любых существующих значений. Вычитая два, мы получаем количество значений x уже присутствующих в списке.

Поскольку модуль bisect использует двоичный поиск, этот метод равен O (log N).

  • 0
    Может ли downvoter оставить комментарий, пожалуйста?
  • 1
    1) Это предполагает, что отдельные элементы известны заранее 2) в худшем случае это O (N * logN), что хуже, чем прямое O (N)
Показать ещё 2 комментария
0

Вы можете разделить и покорить и вычесть подсчеты, когда последний элемент в первом тайме равен первому элементу во второй половине:

def count(l):
    if len(l) <= 1:
        return len(l)
    mid = len(l) // 2
    head, tail = l[:mid], l[mid:]
    return count(head) + count(tail) - (len(head) and len(tail) and head[-1] == tail[0])

чтобы:

count([2,2,3,4,4,5,6,6,6,7,8])

возвращает: 7 (так как у нас есть 7 различных чисел: 2, 3, 4, 5, 6, 7, 8)

  • 0
    Это O (N) да? Вы можете наблюдать это, посчитав количество узлов в дереве рекурсии.
  • 0
    Правда что. Оставим здесь ответ в качестве ссылки, но это действительно не решение O (log n).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню