Поиск k-ой порядковой статистики в двух массивах — различия между версиями
(→Варианты решения) |
(→Варианты решения) |
||
Строка 10: | Строка 10: | ||
Оба решения, приведенные выше, работают за линейное время, то есть приемлемы только при небольших значениях <tex>k</tex>. Следующее решение работает за <tex>O(log(n) + log(m))</tex>. | Оба решения, приведенные выше, работают за линейное время, то есть приемлемы только при небольших значениях <tex>k</tex>. Следующее решение работает за <tex>O(log(n) + log(m))</tex>. | ||
− | Чтобы получить логарифмическую сложность, будем использовать бинарный поиск, который | + | Чтобы получить логарифмическую сложность, будем использовать бинарный поиск, который сокращает область поиска с каждой итерацией. То есть для достижения нужной сложности мы должны на каждой итерации сокращать круг поиска в каждом из массивов. |
Рассмотрим следующую ситуацию: пусть у нас есть элемент <tex>a[i]</tex> из массива <tex>A</tex> и элемент <tex>b[j]</tex> из массива <tex>B</tex> и они связаны неравенством <tex>b[j - 1] < a[i] < b[j]</tex>. Тогда <tex>a[i]</tex> есть <tex>(j + i + 1)</tex>-ый порядковый элемент после слияния массивов. Это объясняется тем, что до <tex>a[i]</tex>-ого элемента идут <tex>(j - 1)</tex> элемент из массива <tex>B</tex>, <tex>i</tex> элементов из массива <tex>A</tex> (включая сам элемент <tex>a[i]</tex>) и так как индексация массивов начинается с нуля, то необходимо прибавить еще <tex>2</tex>. В итоге получаем <tex>(j - 1) + i + 2 = j + i + 1</tex>. Принимая это во внимание, будем выбирать <tex>i</tex> и <tex>j</tex> таким образом, чтобы <tex>j + i + 1 = k</tex>. | Рассмотрим следующую ситуацию: пусть у нас есть элемент <tex>a[i]</tex> из массива <tex>A</tex> и элемент <tex>b[j]</tex> из массива <tex>B</tex> и они связаны неравенством <tex>b[j - 1] < a[i] < b[j]</tex>. Тогда <tex>a[i]</tex> есть <tex>(j + i + 1)</tex>-ый порядковый элемент после слияния массивов. Это объясняется тем, что до <tex>a[i]</tex>-ого элемента идут <tex>(j - 1)</tex> элемент из массива <tex>B</tex>, <tex>i</tex> элементов из массива <tex>A</tex> (включая сам элемент <tex>a[i]</tex>) и так как индексация массивов начинается с нуля, то необходимо прибавить еще <tex>2</tex>. В итоге получаем <tex>(j - 1) + i + 2 = j + i + 1</tex>. Принимая это во внимание, будем выбирать <tex>i</tex> и <tex>j</tex> таким образом, чтобы <tex>j + i + 1 = k</tex>. |
Версия 15:26, 15 апреля 2015
Содержание
Постановка задачи
Пусть даны два отсортированных массива
и размерами и соответственно. Требуется найти -ый порядковый элемент после их слияния. Будем считать, что все элементы в массивах различны и нумеруются с нуля.Варианты решения
Наивное решение
Сольем два массива и просто возьмем элемент с индексом
. Сливание будет выполнено за .Чуть менее наивное решение
Будем использовать два указателя, с помощью которых сможем обойти массивы не сливая их. Поставим указатели на начало каждого из массивов. Будем увеличивать на единицу тот из них, который указывает на меньший элемент. После
-ого добавления сравним элементы, на которых стоят указатели. Меньший из них и будет ответом. Таким образом, мы получим -ый элемент за шагов.Совсем не наивное решение
Оба решения, приведенные выше, работают за линейное время, то есть приемлемы только при небольших значениях
. Следующее решение работает за .Чтобы получить логарифмическую сложность, будем использовать бинарный поиск, который сокращает область поиска с каждой итерацией. То есть для достижения нужной сложности мы должны на каждой итерации сокращать круг поиска в каждом из массивов.
Рассмотрим следующую ситуацию: пусть у нас есть элемент
из массива и элемент из массива и они связаны неравенством . Тогда есть -ый порядковый элемент после слияния массивов. Это объясняется тем, что до -ого элемента идут элемент из массива , элементов из массива (включая сам элемент ) и так как индексация массивов начинается с нуля, то необходимо прибавить еще . В итоге получаем . Принимая это во внимание, будем выбирать и таким образом, чтобы .Подведем промежуточный итог:
- Инвариант
- Если , то и есть -ая порядковая статистика
- Если , то и есть -ая порядковая статистика
Итак, если одно из двух последних условий выполняется, то мы нашли нужный элемент. Иначе нам нужно сократить область поиска, как задумывалось в начале.
Будем использовать
и как опорные точки для разделения массивов. Заметим, что если , то (иначе второе условие бы выполнялось). В таком случае на месте -го элемента может стоять максимум -ый порядковый элемент после слияния массивов (так произойдет в случае, когда ), а значит элемент с номером и все до него в массиве никогда не будут -ой порядковой статистикой.