How to determine if a sequence is bitonic?

后端 未结 5 1130
遥遥无期
遥遥无期 2020-12-23 18:00

A sequence is bitonic if it monotonically increases and then monotonically de- creases, or if it can be circularly shifted to monotonically increase and

5条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2020-12-23 18:17

    • Traverse the array forwards, wrapping around when you hit the end (code below)
    • Count the total number of inflection points you find, if num_inflection_points==2 then your array is bitonic.
    • The runtime of this should be 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;
    }
    
    • Notes, depending on your implementation:

    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.

提交回复
热议问题