A sequence is bitonic if it monotonically increases and then monotonically de- creases, or if it can be circularly shifted to monotonically increase and
num_inflection_points==2 then your array is bitonic.O(n).-
Here's a working example in c++:
bool is_bitonic(const vector& 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;
}
Note 1: Here's the basic idea for traversing an array circularly:
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];)
}
Note 2: It might simplify the code to circularly loop length + 1 elemnts, which will guarantee you find both inflection points.
Note 3: Or, it might simplify the code if you always look for the first inflection point that goes increasing to decreasing (before searching for other inflection points). That way, your scan only has to take worry about finding exactly one other inflection point with the opposite flip.
Note 4: As for your example, you can't use N/2, because the inflection point doesn't necessarily occur at the midpoint of the array.