Какую структуру данных использовать для поиска значения в неотсортированном массиве?

«Какую структуру данных использовать для поиска значения в неотсортированном массиве?» — вопрос из категории Алгоритмы и структуры данных, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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

Алгоритм линейного поиска (O(n)):

int[] array = {5, 2, 9, 1, 7};
int target = 9;
boolean found = false;

for (int value : array) {
    if (value == target) {
        found = true;
        break;
    }
}
System.out.println("Found: " + found); // Found: true

Оптимизация для множественных поисков: Если поиск выполняется часто, эффективнее один раз преобразовать данные в структуру с быстрым поиском:

  1. HashSet (или HashMap):

    • Сложность поиска: O(1) в среднем случае.
    • Подход: Однократно добавить все элементы в HashSet.
    • Недостаток: Требует дополнительной памяти O(n).
      Set<Integer> set = new HashSet<>(Arrays.asList(5, 2, 9, 1, 7));
      boolean found = set.contains(9); // true
  2. Сортировка + бинарный поиск:

    • Сложность: O(n log n) на предварительную сортировку, O(log n) на каждый поиск.
    • Подход: Отсортировать массив (Arrays.sort()), затем использовать Arrays.binarySearch().
    • Недостаток: Изменяет исходный массив или требует его копирования.
      int[] sortedArray = array.clone();
      Arrays.sort(sortedArray); // {1, 2, 5, 7, 9}
      int index = Arrays.binarySearch(sortedArray, 9); // index = 4

Вывод: Для единичного поиска используйте линейный обход. Для множественных — предварительно создайте HashSet.