- Обойдите массив вперед, обернувшись, когда вы дойдете до конца (код ниже)
- Подсчитайте общее количество точек перегиба, которые вы найдете, если
num_inflection_points==2
, то ваш массив битонический. - Время выполнения этого должно быть
O(n)
.
-
Вот рабочий пример на c ++:
bool is_bitonic(const vector<int>& v) {
bool was_decreasing = v.back() > v.front();
int num_inflections = 0;
for (int i = 0; i < v.size() && num_inflections <= 2; i++) {
bool is_decreasing = v[i] > v[(i+1)%v.size()];
// Check if this element and next one are an inflection.
if (was_decreasing != is_decreasing) {
num_inflections++;
was_decreasing = is_decreasing;
}
}
return 2 == num_inflections;
}
- Примечания, в зависимости от вашей реализации:
Примечание 1. Вот основная идея кругового обхода массива:
for (int i = ip_index; i < array_length; i++) {
int index = (i + 1) % array_length; // wraps around to beginning
// Retrieve the value with
DoSomethingWithValue(array[index];)
}
Примечание 2. Это может упростить код для циклического цикла * 1023.* elemnts, который гарантирует, что вы найдете обе точки перегиба.
Примечание 3: Или это может упростить код, если вы всегда будете искать первую точку перегиба, которая увеличивается или уменьшается (перед поиском других точек перегиба),Таким образом, ваше сканирование должно заботиться только о том, чтобы найти ровно одну другую точку перегиба с обратным переворотом.
Примечание 4. Что касается вашего примера, вы не можете использовать N/2
, потому что точка перегиба нене обязательно происходит в средней точке массива.