Algorithm: Modified Binary Search

…衆ロ難τιáo~ 提交于 2019-12-05 12:32:02

I think your code does not handle well the increasing and decreasing part of the array.

Instead of telling you exactly how to do this, here is some tip and I hope you are able to finish it :)

One solution is to first find the point where the array goes from increasing order to decreasing order in O(logn), then based on that, perform a special version of binary search in O(logn).

Let me know in case you don't know how to to this, I will explain more on my answer.

Here is a more complete solution (served only as a reference)

One solution is to first find the point where the array goes from increasing order to decreasing order in O(logn), then based on that, perform a special version of binary search in O(logn).

The first part can be achieved by finding the last point where array[i-1] <= array[i] using a specialized binary search where the mid index moving condition is whether array[mid-1] <= array[mid] instead of whether array[mid] <= target.


Sample Code

To prevent me from being an interview hacker, below only shows how to handle an array without any duplicates. The code will soon removed if necessary:

#include <stdio.h>
#include <stdlib.h>

int find_change_point(int array[], int low, int high, int array_size) {
  int mid;
  for (mid = (low + high) / 2; low <= high; mid = (low + high) / 2) {
    // if true, it implies the point is on the higher side
    if (array[mid - 1] <= array[mid]) {
      if (mid == array_size - 1) {
        return mid;
      }
      // since we already handles equality, only > is needed.
      if (array[mid] > array[mid + 1]) {
        return mid;
      }
      low = mid + 1;
    } else {
      // then simply imply the point is on the lower part
      high = mid - 1;
    }
  }
  return mid;
}

int main() {
  const int SIZE_1 = 8;
  int array_1[SIZE_1] = {3,5,7,14,9,8,2,1};
  int change_point = find_change_point(array_1, 0, SIZE_1 - 1, SIZE_1);
  printf("change_point_1 = %d\n", change_point);

  const int SIZE_2 = 9;
  int array_2[SIZE_2] = {3,5,7,14,15,16,17,19, 20};
  change_point = find_change_point(array_2, 0, SIZE_2 - 1, SIZE_2);
  printf("change_point_2 = %d\n", change_point);

  const int SIZE_3 = 9;
  int array_3[SIZE_3] = {9, 8, 7, 6, 5, 4, 3, 2, 1};
  change_point = find_change_point(array_3, 0, SIZE_3 - 1, SIZE_3);
  printf("change_point_3 = %d\n", change_point);
}

and the output is:

change_point_1 = 3
change_point_2 = 8
change_point_3 = 0

For handling duplications, you need to find its left-end and right-end of the duplication sequence and verify whether they are increasing or decreasing sequence.

The second part has many varieties. One simple solution is to treat them as two arrays, and perform one binary search for each subarray to find your target element.

For your code i think to many branch like "if" operation . Following is simple pseudocode for your reference:

while(1 < (high - low)){
     int mid = (low + high) >> 1;
     (key < A[mid]) ? high = mid : lo = mid;
}
return (key == A[lo]) ? lo : -1;

Hope this can be help you.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!