Ответ 1
Мы можем решить это в O(logn)
время, используя divide и завоевать aka. двоичный поиск. Лучше, чем линейное время. Поэтому нам нужно найти триплет такой, что A[n-1] >= A[n] <= A[n+1]
.
Сначала найдите середину данного массива. Если середина меньше ее левой и больше ее правой. затем верните, вот ваш ответ. Кстати, это было бы базой в вашей рекурсии. Также, если len(arr) < 3
, то тоже возвращаются. другой базой.
Теперь идут сценарии рекурсии. Когда нужно возвращаться, нам нужно будет проверить дальше. Для этого, если середина больше элемента слева от нее, рассмотрим начало слева от массива как подзадачу и рекурсию с этим новым массивом. т.е. в материальных терминах в этой точке мы имели бы ...2
6 ...
с индексом n
равным 6. Поэтому мы перемещаем влево, чтобы увидеть, находится ли элемент слева от 2
триплет.
В противном случае, если середина больше элемента в своем правом подмассиве, тогда рассмотрите середину + 1 справа от массива в качестве подзадачи и рекурсии.
Подробнее Теория: вышеизложенного должно быть достаточно, чтобы понять проблему, но читать дальше. Проблема в основном сводится к поиску локальных минимумов в заданном наборе элементов. Число в массиве называется локальным минимумом, если оно меньше, чем его левое и правое числа, которые точно сводятся к A[n-1] >= A[n] <= A[n+1]
.
Данный массив, такой, что его первые 2 элемента уменьшаются, а последние 2 элемента увеличиваются, чтобы иметь локальные минимумы. Почему это? Докажем это отрицанием. Если первые два числа уменьшаются, а локальных минимумов нет, это означает, что 3-е число меньше 2-го числа. в противном случае вторым номером были бы локальные минимумы. По той же логике 4-й номер должен быть меньше 3-го числа и т.д. И т.д. Поэтому числа в массиве должны быть в порядке убывания. Который нарушает ограничение последних двух чисел в порядке возрастания. Это доказывает отрицание того, что должны быть локальные минимумы.
Вышеупомянутая теория предполагает линейный подход O(n)
, но мы определенно можем сделать лучше. Но теория определенно дает нам другую точку зрения на проблему.
Код: Здесь код python (fyi - был введен в текстовый редактор stackoverflow в обратном порядке, он может ошибочно ошибаться).
def local_minima(arr, start, end):
mid = (start+end)/2
if mid-2 < 0 and mid+1 >= len(arr):
return -1;
if arr[mid-2] > arr[mid-1] and arr[mid-1] < arr[mid]: #found it!
return mid-1;
if arr[mid-1] > arr[mid-2]:
return local_minima(arr, start, mid);
else:
return local_minima(arr, mid, end);
Обратите внимание, что я просто возвращаю индекс n
. Чтобы распечатать тройку, просто возвращаем -1
и +1
в возвращаемый индекс. источник