Какое время O для определения того, находится ли значение в отсортированном массиве?

У меня есть отсортированный массив из 5000 целых чисел. Как быстро я могу определить, является ли случайное целое число членом массива? В общем, было бы неплохо ответить на C и Ruby.

Значения массива имеют вид

c * c + 1

где c может быть любым целым числом от 1 до 5000.

Например:

[2, 5, 10, 17, 26, 37, 50 ...]

Я не ищу, чтобы вычесть один и взять sqrt () и проверить, является ли это int. ;)

Auburnate 22.01.2009 23:06

Ну, вы также можете посмотреть на stackoverflow.com/questions/295579/… для других способов, которые не связаны с просмотром массива.

A. Rex 22.01.2009 23:24

Это всегда O (1) для фиксированного размера;)

Pete Kirkham 22.01.2009 23:25

@A. Рекс: Я собирался порекомендовать то же самое, но я все же думаю, что sqrt будет медленнее, чем максимум из 13 сравнений, которые вам понадобятся при двоичном поиске. Я могу ошибаться.

Bill the Lizard 22.01.2009 23:29

Все ли значения от 1 до 5000 в этом массиве или несколько раз в нем?

Georg Schölly 22.01.2009 23:38

Должен ли он быть в массиве? Как уже отмечали все остальные, двоичный поиск даст вам O (log N), но Тал, специалист по Perl, кое-что знает. Хеширование вашего массива сократит время до O (1).

rtperson 22.01.2009 23:45

Вся эта дискуссия бессмысленна. Нет никаких мыслимых причин для создания этого массива или поиска в нем таким образом.

PeterAllenWebb 23.01.2009 00:45

Также бессмысленно обсуждать время работы Big O для поиска в массиве постоянного размера - O (1) по определению.

mbeckish 23.01.2009 00:50

@ Ящерица Билла: Вы, наверное, правы. Я просто подумал, что это было полезно. знак равно

A. Rex 23.01.2009 11:55
Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
1
9
504
9
Перейти к ответу Данный вопрос помечен как решенный

Ответы 9

log (n) для двоичного поиска на c

O (log n), если в массиве n элементов

Используя двоичный поиск, это время поиска Log (N).

bool ContainsBinarySearch(int[] array, int value) {
  return Array.BinarySearch(arrray, value) >= 0;
}

Двоичный поиск - O (log n)

Википедия

Просто чтобы расширить это: это тесты LGп, то есть бревно2 n. Это делает его O (бревно n). Почему? потому что каждое испытание двоичного поиска делит массив пополам; таким образом, требуется LG n попыток.

Ответ принят как подходящий

Двоичный поиск, как упоминалось другими, - это O (log2N), и его можно закодировать рекурсивно:

   BinarySearch(A[0..N-1], value, low, high) {
       if (high < low)
           return -1 // not found
       mid = (low + high) / 2
       if (A[mid] > value)
           return BinarySearch(A, value, low, mid-1)
       else if (A[mid] < value)
           return BinarySearch(A, value, mid+1, high)
       else
           return mid // found
   }

или итеративно:

   BinarySearch(A[0..N-1], value) {
       low = 0
       high = N - 1
       while (low <= high) {
           mid = (low + high) / 2
           if (A[mid] > value)
               high = mid - 1
           else if (A[mid] < value)
               low = mid + 1
           else
               return mid // found
       }
       return -1 // not found
   }

Однако, если вы ищете самый быстрый способ, вы можете настроить справочную таблицу на основе sqrt(N-1) ваших номеров. Имея всего 5000 слов памяти, вы можете таким образом выполнить поиск O (1).

Объяснение:

Поскольку все ваши числа имеют форму N ^ 2 + 1 для целого числа N от 1 до N, вы можете создать таблицу из N элементов. Элемент в позиции i будет указывать, находится ли i ^ 2 + 1 в вашем массиве или нет. Таблица может быть реализована с помощью простого массива длины N. Для построения потребуется O (N) и N слов пространства. Но как только у вас есть таблица, все поиски выполняются O (1).

Пример:

Вот пример кода на Python, который, как всегда, читается как псевдокод :-)

import math

N = 5000
ar = [17, 26, 37, 50, 10001, 40001]

lookup_table = [0] * N

for val in ar:
    idx = int(math.sqrt(val - 1))
    lookup_table[idx] = 1

def val_exists(val):
    return lookup_table[int(math.sqrt(val - 1))] == 1

print val_exists(37)
print val_exists(65)
print val_exists(40001)
print val_exists(90001)

Построение таблицы занимает не более O (N), а поиск - O (1).

Я бы сказал, что это O (const)! :)

Учитывая случайное число r, легко проверить, может ли это число быть представлено в форме (n * n + 1). Просто проверьте, является ли sqrt (r-1) целым или нет!

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

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

rmeador 22.01.2009 23:40

Технически сложность поиска элемента в массиве фиксированного размера постоянна, поскольку log2 5000 не изменится.

В Perl:

Я бы загрузил значения в статический хеш, и тогда это было бы O (1).

Создайте хэш поиска

lookup_hash {$ _} = 1 foreach (@original_array);

Синтаксис поиска

($ lookup_hash {$ lookup_value}) && print "Нашел в O (1) - здесь нет цикла \ n";

Просто потому, что «видимый» код состоит из одного оператора, это не делает фактический поиск O (1). Поиск хэша - это не операция с постоянным временем, он зависит от размера хэша и конкретного алгоритма поиска (не уверен, какой из них Perl использует для внутренних целей).

DanM 22.01.2009 23:56

DanM - на самом деле хеширование Perl будет очень близко к O (1), особенно для такого количества элементов (т.е. не очень большого)

Eli Bendersky 23.01.2009 00:09

Другие вопросы по теме