Какой алгоритм используется для поиска n-го сортированного подмассива неупорядоченного массива?

Недавно у меня был этот вопрос в интервью, и я потерпел неудачу и теперь ищу ответ.

  • Скажем, у меня есть большой массив из n целых чисел, все разные.

  • Если этот массив был заказан, я мог бы разделить его на x меньше массивы, все размеры y, за исключением, может быть, последнего, что может быть меньше. Я мог бы извлечь n-й подмассив и вернуть его, уже отсортированный.

Пример: Array 4 2 5 1 6 3. Если y = 2 и мне нужен второй массив, это будет 3 4.

Теперь я просто сортировал массив и возвращал n-й подмассив, который принимает O (n log n). Но мне сказали, что существует способ сделать это в O(n + y log y). Я искал в Интернете и ничего не нашел. Идеи?

Ответ 1

Алгоритм, который вы ищете, это Алгоритм выбора, который позволяет находить статистику k-го порядка в линейном времени. Алгоритм довольно сложный, но стандартная библиотека С++ удобно предоставляет его реализацию.

Алгоритм поиска k-го сортированного интервала, который имел в виду у интервьюеров, был следующим:

  • Найти b=(k-1)*y -ый порядок статистики в O (N)
  • Найти e=k*y -ный порядок статистики в O (N)
  • Между b и e будет число y. Храните их в отдельном массиве размером y. Эта операция принимает O (N)
  • Сортировка массива размера y для O (y * log 2 y).

Общая стоимость O (N + N + N + y * log 2 y), то есть O (N + y * log 2 y)

Ответ 2

Вы можете комбинировать std::nth_element и std::sort для этого:

std::vector<int> vec = muchData();
// Fix those bound iterators as needed
auto lower = vec.begin() + k*y;
auto upper = lower + y;

// put right element at lower and partition vector by it
std::nth_element(vec.begin(), lower, vec.end());
// Same for upper, but don't mess up lower
std::nth_element(lower + 1, upper - 1, vec.end());
// Now sort the subarray
std::sort(lower, upper);

[lower, upper) теперь является k-м сортированным подмассивом длины y с требуемой сложностью в среднем.

Проверять для особых случаев, таких как y = 1, перед использованием в реальном мире, но это общая идея.