Related algorithm problems of binary search

Source: Internet
Author: User
Tags arrays


Recent written tests often encounter binary search-related algorithmic questions

1) Rotate the smallest number in the array

2) Find a number in the rotation array

2) Number of occurrences of a number in the sorted array

Reprint please indicate the original blog address: http://blog.csdn.net/gdutxiaoxu/article/details/51292440


About the binary search, you can refer to my blog two-point search for the relevant algorithm problems

For the merge sort, you can refer to my blog. Merge sort recursive and non-recursive implementations (Java)

For quick sorting, you can refer to my blog about the quick sort of related algorithmic questions (Java)

Let me summarize the following one by one.

1 Minimum number of rotated arrays

Title: Move a number of elements at the beginning of an array to the end of the array, which we call the rotation of the array. Enter a rotation of an incrementally sorted array, outputting the smallest element of the rotated array. For example, the array {3,4,5,1,2} is a rotation of {1,2,3,4,5}, and the minimum value of the array is 1.

The rotation of the implementation array is shown by the left rotation string.

As with the binary lookup method, the first element and the last element of the array are pointed to by two pointers, respectively.

We notice that the rotated array can actually be divided into two sorted sub-arrays, and the elements of the preceding sub-arrays are greater than or equal to the elements of the post-face array. We can also notice that the smallest element is just the dividing line of these two sub-arrays. We are trying to find the smallest element with the idea of a two-dollar search method.

First we use two pointers, each pointing to the first and last element of the array. According to the rule of rotation of the topic, the first element should be greater than or equal to the last element (this is not exactly right, there are exceptions.) The exception is discussed later).

Then we get the elements in the middle of the array. If the intermediate element is in the preceding increment sub-array, it should be greater than or equal to the element that the first pointer points to. The smallest element in the array should be at the back of the intermediate element. We can point the first pointer to the middle element so that we can narrow the range we are looking for. Similarly, if an intermediate element is in a subsequent increment of a subarray, it should be less than or equal to the element that the second pointer points to. At this point the smallest element in the array should precede the intermediate element. We can point the second pointer to the middle element, which can also narrow the search. We then use the updated two pointers, to get and compare the new intermediate elements, loop down.

According to the above idea, our first pointer always points to the element that increments the array earlier, and the second pointer always points to the element that increments the array later. The last pointer will point to the last element of the preceding subarray, and the second pointer will point to the first element of the post-face array. That is, they eventually point to two adjacent elements, and the second pointer points to just the smallest element. This is the condition of the end of the loop.

Core Implementation code:

int Min (int *numbers, int length) {if (numbers = = NULL | | length <= 0) return;
    int index1 = 0;
    int index2 = length-1;
    int indexmid = index1; while (Numbers[index1] >= Numbers[index2]) {if (index2-index1 = = 1) {Indexmid = index
            2;
        Break
        } Indexmid = (index1 + index2)/2; If the subscript is equal to the three digits pointed to by index1, Index2, and Indexmid, you can only look in order if (numbers[index1] = Numbers[index2] && Numbers[indexmid]
 
        = = Numbers[index1]) return Mininorder (Numbers, index1, index2);
        if (Numbers[indexmid] >= numbers[index1]) index1 = Indexmid;
    else if (Numbers[indexmid] <= numbers[index2]) index2 = Indexmid;
} return Numbers[indexmid];
    }//Order lookup int Mininorder (int *numbers, int index1, int index2) {int result = Numbers[index1]; for (int i = index1 + 1; I <= index2; ++i) {if (Result > Numbers[i]) reSult = Numbers[i];
} return result; }



Note: When the number of two pointers is the same as the number in the middle of them, we cannot tell if the median number is in the preceding or subsequent sub-array, and you cannot move the two pointers to narrow the search. At this point, we have to adopt a sequential lookup method.

2 Rotate an array to find a number

Requirements

Given an array of rotations without repeating elements (which corresponds to the original array is ordered), the subscript of the given element within the rotated array (no return-1 is present).

For example

The ordered array is {0,1,2,4,5,6,7}, and one of its rotated arrays is {4,5,6,7,0,1,2}. Element 6 in the rotation array, return 2 element 3 not in the rotation array, return 1

Analysis

Traversing through, can be easily done, the time complexity of O (n), because it is ordered array rotation is obtained, this is certainly not the optimal solution. Orderly, instinctive reflection using binary search, give an example to see the features

You can see that the middle position at least one of the two segments is ordered (not the left, or the right), then you can use the binary search in an orderly range, if it is no longer in an orderly range, go to the other half to find.

Reference Code

int search (int a[], int n, int target) {
        int beg = 0;
        int end = n-1;
        while (beg <= end)
        {
            int mid = Beg + (End-beg)/2;
            if (a[mid] = = target)
                return mid;
            if (A[beg]  <= A[mid])
            {
                if (A[beg] <= target && target < A[mid])
                    end = Mid-1;
                else 
                    Beg = mid + 1;
            }
            else
            {
                if (A[mid] < target && target <= a[end])
                    Beg = mid + 1;
                else
                    end = mid-1;
            }
        }
        return-1;
    }

Extended

There is no repetition of the above elements, now slightly expanded, there can be duplicate elements, the other requirements are unchanged.

Ideas

The general idea is the same as the original, which is required to compare A[beg] with A[mid] A[beg] < A[mid] ———— left ordered A[beg] > A[mid] ———— right ordered A[beg] = A[mid] ———— ++beg

Boolean search (int a[], int n, int target) {
        int beg = 0;
        int end = n-1;
        while (beg <= end)
        {
            int mid = Beg + (End-beg)/2;
            if (a[mid] = = target) 
                return true;
            if (A[beg] < A[mid])
            {
                if (A[beg] <= target && target < A[mid])
                    end = Mid-1;
                else
                    Beg = mid + 1;
            }
            else 0if (A[beg] > A[mid])
            {
                if (A[mid] < target && target <= a[end])
                    Beg = mid + 1;
                else
                    end = mid-1;
            }
            else
                ++beg;
        }
        return false;
    }


number of occurrences of 3 numbers in a sorted array



//binary find, two points find the first occurrence of key position, two points to find the last occurrence of the key//return the two subtract +1 or find the first occurrence of the position, looking backwards 
int binarysearchfirstpos (int * Iarr, int l, int h, int key) {while (L <= h) {int mid = (L + h)/

        2;

        if (Iarr[mid] < key) L = Mid +1;

        ElseIf (Iarr[mid] > key) h = mid-1;

            else {if (mid = = L | | iarr[mid-1]! = key) return mid;

        else H = mid-1;

}} return-1;  } int Binarysearchlastpos (int * Iarr, int l, int h, int key) {while (L <= h) {int mid = (L + h)/

        2;

        if (Iarr[mid] < key) L = mid + 1;

        ElseIf (Iarr[mid] > key) h = mid-1;

            else {if (mid = = H | | Iarr[mid + 1]! = key) return mid;

        else L = mid + 1;

}} return-1;

    } int Numofkey (int * iarr, int length, int key) {int firstpos = Binarysearchfirstpos (Iarr, 0, length-1, key); int lastPos = Binarysearchlastpos (Iarr, 0, length-1, key);

    cout << firstpos << "\ t" << lastpos << Endl;;

    if (Firstpos = =-1) return0;

Elsereturn Lastpos-firstpos + 1; }

I wrote it here today and went to bed.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.