关于Binary Search的写法总结

来源:互联网 发布:单片机和嵌入式的区别 编辑:程序博客网 时间:2024/05/16 07:41

1. 使用闭区间,初始化 start = 0, end = n-1。

2. 循环条件  while (start <= end)

3. 中间元素的取法: int mid = low + ((high - low) / 2);

一段典型的code:

1:     public static int binarySearch(int[] a, int key) {2:         int low = 0;3:         int high = a.length - 1;4:5:         while (low <= high) {6:             int mid = low + (high-low) / 2;7:             int midVal = a[mid];8:9:             if (midVal < key)10:                 low = mid + 111:             else if (midVal > key)12:                 high = mid - 1;13:             else14:                 return mid; // key found15:         }16:         return -1;  // key not found.17:     }


Leetcode 相关题目: Search for a Range, Search in Rotated Sorted Array, Search in Rotated Sorted Array II

Leetcode: Search in Rotated Sorted Array 代码:

4. 边界条件。当end-start = 1时,注意mid = start,此时如果A[start]不符合条件,应该转向start = mid+1,搜索第二个元素,而如果end = mid-1,则直接退出循环而发生错误。

直观来看,如果int mid = low + ((high - low) / 2); 则应将 if(A[start] < A[mid])和 if(A[start] == A[mid])合并为一种情况来处理(都应搜索后半部分)。

如果int mid = low + ((high - low +1) / 2); 应将if(A[mid] < A[end])和 if(A[end] == A[mid]) 合并为一种情况(都应搜索前半部分)。


class Solution {public:    int search(int A[], int n, int target)     {        if(n == 0) return -1;        //if(n == 1) return A[0] == target?0:-1;                int start = 0, end = n-1;                while(start <= end)        {            int mid = start + (end - start)/2;            if(A[mid] == target) return mid;            if(A[start] <= A[mid])            {                if(A[start] <= target && target < A[mid])                    end = mid-1;                else                    start = mid+1;            }            else            {                if(A[mid] < target && target <= A[end])                    start = mid+1;                else                    end = mid-1;            }        }        return -1;    }};

Leetcode: Search in Rotated Sorted Array II 代码:

class Solution {public:    bool search(int A[], int n, int target) {        if(n == 0) return false;                int start = 0, end = n-1;        while(start <= end)        {            int mid = start + (end - start)/2;            if(A[mid] == target) return true;                        if(A[start] < A[mid])            {                if(A[start] <= target && target < A[mid])                    end = mid-1;                else                    start = mid+1;            }            else if(A[start] > A[mid])            {                if(A[mid] < target && target <= A[end])                    start = mid+1;                else                    end = mid-1;            }            if(A[start] == A[mid])                start++;            if(A[mid] == A[end])                end--;        }        return false;    }};

题目: Find the minimum element in a sorted and rotated array

http://www.geeksforgeeks.org/find-minimum-element-in-a-sorted-and-rotated-array/

int findMin(int arr[], int n){int low = 0;int high = n-1;if(n == 1) return arr[0];while (low <= high){    // Find mid    int mid = low + (high - low)/2;    if(mid-1 >= 0 && arr[mid-1] > arr[mid])    return arr[mid];    if(mid+1 < n && arr[mid] > arr[mid+1])    return arr[mid+1];    if(arr[low] <= arr[mid])    low = mid + 1;    else    low = mid - 1;}return arr[0];}// Driver program to test above functionsint main(){    int arr1[] =  {5, 6, 1, 2, 3, 4};    int n1 = sizeof(arr1)/sizeof(arr1[0]);    printf("The minimum element is %d\n", findMin(arr1, n1));    int arr2[] =  {1, 2, 3, 4};    int n2 = sizeof(arr2)/sizeof(arr2[0]);    printf("The minimum element is %d\n", findMin(arr2, n2));    int arr3[] =  {1};    int n3 = sizeof(arr3)/sizeof(arr3[0]);    printf("The minimum element is %d\n", findMin(arr3, n3));    int arr4[] =  {1, 2};    int n4 = sizeof(arr4)/sizeof(arr4[0]);    printf("The minimum element is %d\n", findMin(arr4, n4));    int arr5[] =  {2, 1};    int n5 = sizeof(arr5)/sizeof(arr5[0]);    printf("The minimum element is %d\n", findMin(arr5, n5));    int arr6[] =  {5, 6, 7, 1, 2, 3, 4};    int n6 = sizeof(arr6)/sizeof(arr6[0]);    printf("The minimum element is %d\n", findMin(arr6, n6));    int arr7[] =  {1, 2, 3, 4, 5, 6, 7};    int n7 = sizeof(arr7)/sizeof(arr7[0]);    printf("The minimum element is %d\n", findMin(arr7, n7));    int arr8[] =  {2, 3, 4, 5, 6, 7, 8, 1};    int n8 = sizeof(arr8)/sizeof(arr8[0]);    printf("The minimum element is %d\n", findMin(arr8, n8));    int arr9[] =  {3, 4, 5, 1, 2};    int n9 = sizeof(arr9)/sizeof(arr9[0]);    printf("The minimum element is %d\n", findMin(arr9, n9));    return 0;}


有重复元素的情况:

class Solution {public:    int findMin(vector<int> &arr) {        const int n = arr.size();    <span style="white-space:pre"></span>int low = 0;    <span style="white-space:pre"></span>int high = n-1;    <span style="white-space:pre"></span>if(n == 1) return arr[0];            <span style="white-space:pre"></span>while (low <= high)    <span style="white-space:pre"></span>{    <span style="white-space:pre"></span>    // Find mid    <span style="white-space:pre"></span>    int mid = low + (high - low)/2;    <span style="white-space:pre"></span>    if(mid-1 >= 0 && arr[mid-1] > arr[mid])    <span style="white-space:pre"></span>    <span style="white-space:pre"></span>return arr[mid];    <span style="white-space:pre"></span>    if(mid+1 < n && arr[mid] > arr[mid+1])    <span style="white-space:pre"></span>    <span style="white-space:pre"></span>return arr[mid+1];                if(arr[mid] < arr[high])                high = mid-1;            else if(arr[mid] > arr[high])                low = mid+1;            else                high--;    <span style="white-space:pre"></span>}    <span style="white-space:pre"></span>return arr[0];    }};

总结: 这两个题目中,如果元素有重复,只能利用以下代码段,逐一跳过重复元素。运行时间介于O(logN)和O(n)之间。

    if(arr[low] == arr[mid])    low++;    else if(arr[mid] == arr[high])    high--;


0 0
原创粉丝点击