Эта проблема не может быть решена в гарантированной временной сложностью быстрее, чем O (n) и вообще не может быть решена для определенных массивов. Бинарный поиск выполняется в O (log n) для отсортированного массива, но большой массив не может быть отсортирован и в худшем случае потребует одного или нескольких сравнений на элемент, что является O (n). Лучшая гарантированная временная сложность - O (n) с тривиальным алгоритмом: сравнивайте каждый элемент со своим соседом, пока не найдете «точку поворота» с A[i] > A[i+1]
. Однако, если вы используете поиск по ширине, вам может повезти и найти «поворотную точку» на ранней стадии.
Доказательство того, что проблема неразрешима для некоторых массивов: пусть массив M = [A B]
будет нашим большим массивом. Чтобы найти точку, где встречаются массивы, мы ищем индекс i
, где M[i] > M[i+1]
. Теперь позвольте A=[1 2 3]
и B=[4 5]
. В массиве M
нет индекса, для которого выполняется условие, поэтому проблема не разрешима для некоторых массивов.
Неофициальное доказательство для первых: пусть M=[A B]
и A=[1..x]
и B=[(x+1)..y]
- это два отсортированных массива. Затем поменяйте местами позиции x
и y
в M
. У нас нет способа найти индекс x
без (в худшем случае) проверки каждого индекса, таким образом, проблема O (n).
Двоичный поиск основан на возможности исключить половину пространства решений с каждым сравнением, но в этом случае мы не можем устранить что-либо из массива, и поэтому мы не можем добиться лучшего результата, чем линейный поиск.
(С практической точки зрения, вы никогда не должны делать это в программе. Два массива должны быть разделены. Если это невозможно, добавьте длину любого массива в большом массиве.)
Изменить: изменил мой ответ после того, как вопрос был обновлен. Это можно сделать быстрее, чем линейное время для . Некоторые массивы, но не все возможные массивы.Вот моя идея для алгоритма с помощью поиска в ширину:
Start with the interval [0..n-1] where n is the length of the big array.
Make a list of intervals and put the starting interval in it.
For each interval in the list:
if the interval is only two elements and the first element is greater than the last
we found the turning point, return it
else if the interval is two elements or less
remove it from the list
else if the first element of the interval is greater than the last
turning point is in this interval
clear the list
split this interval in two equal parts and add them to the list
else
split this interval in two equal parts and replace this interval in the list with the two parts
Я думаю, что в ширину первый подход увеличит шансы найти интервал, где A[first] > A[last]
рано. Обратите внимание, что этот подход не будет работать, если точка поворота находится между двумя интервалами, но вам нужно начать. Я бы сам это испытал, но, к сожалению, сейчас у меня нет времени.
И ваш вопрос? Также, если вы что-то знаете и не можете это доказать, по определению вы не считаете, что вы правы? Просто говоря, возможно, захочется добавить немного больше мысли и вопросительный знак в ваш «вопрос». – CalebB
O (n) будет линейным поиском, то есть вы можете посмотреть на каждый элемент в «большом массиве». Если вы посмотрите на каждый элемент, вы должны найти тот, который ищете, если он существует. Где двоичный поиск? –
Я думаю, что могу дать вам ответ, но мне понадобится дополнительная информация о двух массивах (назовите их A и B). Q1: Имеют ли они перекрывающиеся значения? Все ли значения в A <все в B? Q2: У вас всегда есть (например,): A: 1,2,3 B: 7,8,9', или у вас есть «A: 1,2,3,4,5 B: 4,7,9'? Q3: Как насчет относительных длин A/B? В принципе, добавьте столько информации, сколько сможете. У вас есть репрезентативные примеры данных, которые вы можете опубликовать, несколько случаев, показывающих все возможности, помогут. –