65
правок
Изменения
м
Найдем индекс последнего элемента левого массиваМы имеем массив, образованный из двух отсортированных массивов, заменив условие записанных один в конец другого. Рассмотрим разные примеры таких массивов (вертикальная черта означает границу между двумя маленькими массивами, образующими большой, никакой смысловой нагрузки она не несет, она нужна лишь для облегчения понимания):# <tex>if</tex> на <tex>a[m] < a[m-\{ 1]</tex>. Так мы найдем единственный элемент в массиве, который меньше предыдущего элемента (все остальные элементы больше предыдущего3, так как массивы отсортированы по возрастанию). Однако такой алгоритм не будет работать5 \mid 2, если левый массив длиннее4, чем правый, и <tex>last6 \}</tex> будет равняться начальному значению или <tex>l\{ 2, 4, 6 \mid 1, 3, 5 \}</tex>{{---}} самые частые варианты. Поэтому будем запускать такой алгоритм рекурсивно, если # <tex>last\{ 100 \mid 1 \}</tex> равно начальному значению {{---}} оба массива имеют длину <tex>l1</tex>, беря за новое начальное значение .# <tex>l\{ 1,2,3 \mid 4,5,6 \}</tex> середину {{---}} все элементы из второго массива. Таким образом мы запустим бинарный поиск еще <tex>Oбольше последнего (\log nмаксимального)</tex> разэлемента из первого массива. Стоит заметить, постоянно уменьшая что массив в два раза. Тогда через этом примере не отличим от массивов: <tex>O(\log n)</tex> итераций либо левый массив перестанет быть длиннее{ 1 \mid 2,3,4, чем правый5, и значение <tex>last6 \}</tex> окажется отличным от , <tex>a</tex> (начальное значение <tex>l</tex>)\{ 1, либо длина массива станет равной двум и рекурсия потеряет всякий смысл (если в таком случае <tex>last</tex> останется равным <tex>a</tex>2 \mid 3, то4, значит5, что первый элемент правого массива больше последнего элемента левого массива. Тогда два массива будут являться одним массивом отсортированным по возрастанию). После выполнения этого алгоритма <tex>last6 \}</tex> и будет номером последнего элемента из левого массиватому подобных.
<code> <font color="green">// Поиск Запустить сразу бинарный поиск на таком массиве (образованном из двух маленьких) не представляется разумным, так как массив не будет обязательно отсортированным. Поэтому попробуем найти индекс последнего элемента левого массива</font> '''int''' a = 0 '''int''' b = n + 1 '''function''' indexOfLastLeftArrayElement('''int''' a,'''int''' b) '''int''' l = a '''int''' r = b '''while''' l < r - 1 <font color="green">// Запускаем циклчтобы потом запустить бинарный поиск два раза на отсортированных массивах...</font> m = Найти последний элемент левого массива с помощью алгоритмов поиска, которые ищут максимум на массиве тоже не представляется возможным, потому что элементы правого массива (l + rвсе или некоторые) / 2 <font color="green">// m {{---}} середина области поиска.</font> '''if''' a[m] < a[m - 1] <font color="green">// Сравнение с предыдущим.могут быть больше последнего элемента левого массива..</font> l = m '''else''' r = m '''int''' last = l '''if''' last == a '''and''' r - (a + b) / 2 > 1 indexOfLastLeftArrayElement((a + b) / 2, r)</code>
ПроверимЗначит, равен ли нам следует разработать алгоритм, который будет искать максимально быстро конец левого массива. Утверждается, что в худшем случае такому алгоритму придется сделать <tex>last</tex> <tex>aO(n)</tex>сравнений. Если да, то запустим бинарный поиск Такой алгоритм на массиве от <tex>0\{ 1,2,3 \mid 4,5,6 \}</tex> до <tex>n</tex>. Иначедолжен будет убедиться, что элементы возрастают, зная номер последнего элемента левого массивано для этого ему придется сравнить все соседние элементы, запустим два раза левосторонний бинарный поискпотому что массив может быть таким: на массиве от <tex>\{ 1,2,3, 4 \mid \textbf{0} ,6 \}</tex> до . При этом все элементы, кроме пятого не меняются, значит, по другим элементам невозможно меньше, чем за <tex>lastO(n)</tex>определить, и возрастает ли массив на массиве от <tex>last + 1</tex> до всей своей длине или нет. Для того, чтобы за <tex>O(n)</tex>найти элемент в массиве пройти по всем элементам массива и сравнить их с искомым.
Время выполнения алгоритма {{---}} <tex>O(\log^2 n)</tex> (мы запускаем бинарный поиск, который требует <tex>O(\log n)</tex> времени <tex>O(\log n)</tex> раз).
изменен алгоритм 7.2
==='''Применение поиска на двух отсортированных по возрастанию массивах, записанных один в конец другого'''===
==='''Применение поиска на циклически сдвинутом массиве, образованном приписыванием отсортированного по убыванию массива в конец отсортированного по возрастанию'''===