Summary of classical interview questions-binary search and its variants

Source: Internet
Author: User

Binary Search is a frequently used question in technical interviews. First of all, we will look into this question.CodeGenerally very short ---- No more than 50 rows. Therefore, it is very suitable for technical test or interview questions.

I have done some questions before, many of which are BSAlgorithm.

1. Traditional Binary Search

1.1. The most common BS algorithm is to give an array with a sorted order, and then find whether a number is in the array. If a subscript is given, if not,-1 is returned.

 
Template <typename T> int binarysearch (const t vdata [], int nsize, const T & query) {int L, U, M; L = 0; u = nsize-1; while (L <= u) // The algorithm must note the selected L and U. If the U is selected as the size, this condition will be different {M = (L + U) /2; If (vdata [m] = query) // returns {return m;} else if (vdata [m]> query) // The current element is greater than {u = m-1;} else {L = m + 1;} return-1 ;}

. What is a little more complex than the common BS algorithm is to find a specified string in the dictionary.

For all input words, we can use the Sorting Algorithm to sort all words in Lexicographic Order, and then use the BS algorithm to find the subscript of the given element.

The Code is as follows:

 
# Define maxcharlen 50int binarysearch (const char directionary [] [maxcharlen], int nsize, const char * pquery) {int L, U; L = 0; u = nsize-1; int m; int cmpresult; while (L <= u) {M = (L + u)/2; cmpresult = strcmp (directionary [m], pquery ); // Save the result first to avoid being calculated several times if (cmpresult = 0) {return m;} else if (cmpresult = 1) {u = m-1 ;} else {L = m + 1 ;}} return-1 ;}

2. Empty bianry search

A description of this problem may be as follows:

In a given string sequence (sorted in Lexicographic Order), there are some empty strings. Please find the position of the given string.-1 is not returned in it.

For example, char directionary [] = {"", "A", "AB", "BB", "cc", "ZZ ", "AB" is required in ";

Here we need to add some processing. After finding the central point of binary search, if it is empty, we need to move the current m

# Include <stdio. h> # include <string. h> # include <memory. h> # define maxcharlen 50int binarysearch (const char directionary [] [maxcharlen], int nsize, const char * pquery) {int L, U; L = 0; U = nsize-1; int m; int cmpresult; while (L <= u) {M = (L + u)/2; while (M> L & direary ary [m] [0] = '\ 0') // This location leaves a bug with a slight carelessness, maybe I still have bugs here. {M --;} cmpresult = strcmp (direary ary [m], pquery); If (cmpresult = 0) {return m;} else if (cmpresult = 1) {u = m-1;} else {L = m + 1;} return-1;} int main () // test cases. {const char directionary [] [maxcharlen] = {"", "AA", "", "BB", "", "cc", "DD", "E ", "", "", "FF"}; const char Query [] [maxcharlen] = {"AA", "BB", "cc", "DD ", "KK", "E"}; For (INT I = 0; I <6; I ++) {printf ("% d", binarysearch (direary ary, 11, query [I]);} return 0 ;}

 

3. rotated sorted Array

This problem is described as follows: we know that we have an array, which is generated by rotate based on a sort array.

For example, 3 4 5 1 2 is an array that complies with the above statement.

There are two tasks:

3.1 search for a specific element ).

In the analysis of such problems, the core idea should be that, no matter the array [L, u] is separated, [M-1], [M + 1, u] at least one of them must be sorted, and all the elements in the sorted range will not overlap with the other.

For example, 3 4 5 1 2, if divided into 3 4, 5 1 2, there will be no overlap, that is, they still meet the definition of the original ratated sorted array.

Therefore, binary search can be used for search.

However, these codes are especially easy to write bugs, although they seem simple.

# Include <stdio. h> # include <string. h> # include <memory. h> bool inrange (int l, int U, int query) {return query> = L & query <= u;} int binarysearch (INT rotatedarray [], int nsize, int query) {int lower, upper; lower = 0, upper = nsize-1; int m; while (lower <= upper) {M = (lower + upper)/2; if (rotatedarray [m] = query) {return m;} If (rotatedarray [m]> = rotatedarray [lower]) // if the first interval is a sorting interval {If (inrange (rotatedarray [lower], rotatedarray [m], query )) // if the current search is in the sorting range {upper = m-1;} else // the retrieval element is not in the sorting range {lower = m + 1 ;}} else // the other half is the sorting interval {If (inrange (rotatedarray [m], rotatedarray [upper], query) // within the sorting interval {lower = m + 1 ;} else // not in the sorting range {upper = m-1 ;}} return-1 ;}int main () {int A [] = {3, 5, 7, 9, 0, 2}; For (INT I = 0; I <10; I ++) {printf ("I: % d is at % d \ n", I, binarysearch (A, 6, I);} return 0 ;}

3.2 search for the minumum or maximum)

If the range we are looking for is a [lower] <A [upper], we can conclude that the range we are currently searching is in full order and there is no rotated, you can directly return a [lower].

If lower = upper, we only have one element, or we can directly return a [lower];

In other cases, we can use binary search.

If a [m]> = A [lower], it indicates that a [lower]-> A [m] is sorted, A [lower] <A [upper] does not meet the conditions, so the search area must be on the other side.

Otherwise, the search area is located in a [m], a [lower].

Int findmin (int A [], int lower, int upper) {if (a [lower] <= A [upper]) // contains 2 cases, 1: minimum interval 2: If the entire region is already a sorting interval, the minimum number {return lower;} int M = (lower + upper)/2 is directly returned; if (A [m]> = A [lower]) // if lower... M is the sorting interval, and the entire large interval is not the sorting interval, then the next search is transferred to m + 1, upper. {// equal sign (M = lowerreturn findmin (a, m + 1, upper) in order to prevent the input from being 6 1 );} else {return findmin (A, lower, m); // otherwise, search for the current range} int main () // generate test case {int A [10]; for (INT I = 0; I <6; I ++) {for (Int J = 0; j <6; j ++) {A [(I + J) % 6] = J ;}for (Int J = 0; j <6; j ++) {printf ("% d", a [J]);} printf ("\ Nmin at % d \ n", findmin (A, 0, 5);} return 0 ;}

4. count the number of times

This topic can be described as follows:

In an sorted array, some elements are repeated. We write a function to return the number of occurrences of the given number.

For example, input data 1 2 2 3 3 3 5 5. If input 2, 2 is returned because 2 appears twice in the array.

This problem can be introduced into two subproblems to find the first appearance location of query (Q) and the last occurrence location of Q.

We can call it lower_bound, and upper_bound.

Int findlowerbound (int A [], int nsize, int query) {int lower, upper; int m; lower = 0, upper = nsize-1; while (lower <= upper) {M = (lower + upper)> 1; if (a [m] = query) {While (A [-- m] = query ); return m + 1;} else if (a [m]> query) {upper = m-1;} else {lower = m + 1;} return-1 ;} int findupperbound (int A [], int nsize, int query) {int lower, upper, M; lower = 0, upper = nsize-1; while (lower <= upper) {M = (lower + Upper)> 1; if (a [m] = query) {While (A [++ m] = query); Return s-1 ;} else if (a [m]> query) {upper = m-1 ;}else {lower = m + 1 ;}} return-1 ;}int main () // generate test case {int A [] = {1, 2, 2, 3, 3, 3, 5, 5}; // size is 9int L, U; // int * P = lower_bound (A, A + 9, 0); For (INT I = 0; I <7; I ++) {L = findlowerbound (, 9, I); U = findupperbound (A, 9, I); If (L! =-1) {printf ("L: % d u: % d (u-l): % d \ n", l, u, u-L + 1 );} else {printf ("can't find \ n") ;}} return 0 ;}

Supplement: (thanks to nickmouse)

However, in extreme cases, the complexity of this algorithm is reduced to O (n), and some improved code is provided.

By nickmouse:

 
# Include <stdio. h> int bsearch_lowerbound (int A [], int N, int X) {int L = 0, r = n-1; while (L + 1 <R) {int M = (L + r)/2; if (a [m]> = x) r = m; elsel = m + 1 ;} if (A [l] = x) return l; else if (a [R] = x) return r; elsereturn-1;} int bsearch_upperbound (int A [], int N, int X) {int L = 0, r = n-1; while (L + 1 <r) {int M = (L + r)/2; if (A [m] <= x) L = m; elser = m-1;} if (a [R] = x) return R; else if (a [l] = x) return l; elsereturn-1;} int main () {int A [] = {, 2, 3, 3, 3, 5}; For (INT I = 0; I <6; I ++) {printf ("% d \ n", bsearch_lowerbound (A, 7, I ));} return 0 ;}

5. You need to find the first number that is greater than (or less than) the specified number.

A little hard to understand. Here is an example.

For example, if the input value is 7, 8 is returned, because 8 is the first number greater than input: 7.

In fact, this algorithm plays an important role in the longest incremental sub-sequence of O (nlog (N). Each time we scan a number, we need to know this number, it can be used as the final element of the ascending subsequence with a length of several.

 
// 1 4 5 8 ---> 7int findfirstlarger (int A [], int nsize, int query) {int lower = 0; int upper = nsize-1; int m; while (lower <= upper) {M = (lower + upper)/2; if (a [m] <query) {lower = m + 1 ;} else {upper = m-1 ;}} return lower;} int main () {int A [] = {1, 4, 5, 8 }; // size is 9for (INT I = 0; I <10; I ++) {printf ("I: % d at: % d \ n", I, findfirstlarger (A, 4, I);} return 0 ;}

6. Find an element in the column-and-column sorting matrix.

For example:

1 5 7 10

2 6 8 15

4 9 11 16

12 13 19 21

If the input values are in ascending order of rows, the input values are in ascending order of columns. Now you need to find an element. If it exists,-1 is output.

Because rows and columns are sorted in order, for any element, all the elements on its left are larger than those on it, and the following elements are larger than it, we can design a binary search. This query starts from the last element of row 0th. Based on the comparison results, the entire range is determined to be down or left covered.

The Code is as follows:

 
Bool searchinrowcolsortedmatrix (const int data [], int nrow, int ncol, int query, Int & Trow, Int & tcol) {int irow, icol; irow = 0; icol = ncol-1; int t; while (irow <nrow & icol> = 0) {T = data [irow * ncol + icol]; // get the current data. if (t = query) // find it {Trow = irow; tcol = icol; return true;} else if (T <query) // eleminate the rest of the elements in the current row, who are less than T. {irow ++;} else // eleminate all the rest elements in Current Col, who are greater than T. {icol --;} return false ;}

Conclusion:

The above code may have bugs in some places, although I have done some tests, including a positive test of all internal elements, and a reverse test not in the search array. These codes are indeed prone to bugs. for large companies, such as MS, that are more important to code, bug-free companies may often take questions to test the on-site programming capabilities. However, I still have a lot of water and need to work hard to write the bug-free code.

 

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.