Showing posts with label Binary Search. Show all posts
Showing posts with label Binary Search. Show all posts

Saturday, August 13, 2016

Guess Number higher or lower

We are playing the Guess Game. The game is as follows:

I pick a number from 1 to n. You have to guess which number I picked.

Every time you guess wrong, I'll tell you whether the number is higher or lower.

You call a pre-defined API guess(int num) which returns 3 possible results (-1, 1, or 0):

-1 : My number is lower
1 : My number is higher
0 : Congrats! You got it!
Example:
n = 10, I pick 6.

Return 6.
http://www.programcreek.com/2014/07/leetcode-guess-number-higher-or-lower-java/

Saturday, August 6, 2016

Search in an almost sorted array

Given an array which is sorted, but after sorting some elements are moved to either of the adjacent positions, i.e., arr[i] may be present at arr[i+1] or arr[i-1]. Write an efficient function to search an element in this array. Basically the element arr[i] can only be swapped with either arr[i+1] or arr[i-1].

For example consider the array {2, 3, 10, 4, 40}, 4 is moved to next position and 10 is moved to previous position.

Example:

Input: arr[] =  {10, 3, 40, 20, 50, 80, 70}, key = 40
Output: 2
Output is index of 40 in given array

Input: arr[] =  {10, 3, 40, 20, 50, 80, 70}, key = 90
Output: -1
-1 is returned to indicate element is not present
http://www.geeksforgeeks.org/search-almost-sorted-array/

Search an element in an array where difference between adjacent elements is 1

Given an array where difference between adjacent elements is 1, write an algorithm to search for an element in the array and return the position of the element (return the first occurrence).

Examples:
Let element to be searched be x
Input: arr[] = {8, 7, 6, 7, 6, 5, 4, 3, 2, 3, 4, 3}
       x = 3
Output: Element 3 found at index 7
Input: arr[] =  {1, 2, 3, 4, 5, 4}
       x = 5
Output: Element 5 found at index 4

http://www.geeksforgeeks.org/search-an-element-in-an-array-where-difference-between-adjacent-elements-is-1/

Find the element that appears once in a sorted array

Given a sorted array in which all elements appear twice (one after one) and one element appears only once. Find that element in O(log n) complexity.

Example:

Input:   arr[] = {1, 1, 3, 3, 4, 5, 5, 7, 7, 8, 8}
Output:  4

Input:   arr[] = {1, 1, 3, 3, 4, 4, 5, 5, 7, 7, 8}
Output:  8

http://www.geeksforgeeks.org/find-the-element-that-appears-once-in-a-sorted-array/

Find k closest elements to a given value

Given a sorted array arr[] and a value X, find the k closest elements to X in arr[].
Examples:

Input: K = 4, X = 35
arr[] = {12, 16, 22, 30, 35, 39, 42, 45, 48, 50, 53, 55, 56}
Output: 30 39 42 45

Method:
1) Start from the first element and search for the crossover point (The point before which elements are smaller than or equal to X and after which elements are greater). We will use Binary search for this.This step takes O(logn) time.
2) Once we find the crossover point, we can compare elements on both sides of crossover point to print k closest elements. This step takes O(k) time.
Time: For k elements it takes O(Logn + k) time.
http://www.geeksforgeeks.org/find-k-closest-elements-given-value/

Friday, August 5, 2016

Find frequency of each element in a limited range array in less than O(n) time

Find frequency of each element in a limited range array in less than O(n) time
Given an sorted array of positive integers, count number of occurrences for each element in the array. Assume all elements in the array are less than some constant M.

Do this without traversing the complete array. i.e. expected time complexity is less than O(n).

http://www.geeksforgeeks.org/find-frequency-of-each-element-in-a-limited-range-array-in-less-than-on-time/

Find Square and cubic root of a number

Given a number n, find the cube root of n.
Examples:

Input:  n = 3
Output: Cubic Root is 1.442250

Input: n = 8
Output: Cubic Root is 2.000000
http://www.geeksforgeeks.org/find-cubic-root-of-a-number/

Square root of an integer:
http://www.geeksforgeeks.org/square-root-of-an-integer/

Tuesday, July 26, 2016

Find a peak element in a Given Array

In this arti­cle we will dis­cuss an algo­rithm to Find a peak ele­ment in a Given Array. We will see the recur­sion tech­niques to solve this problem.
Peak Ele­ment: peak ele­ment is the ele­ment which is greater than or equal to both of its neighbors.
http://www.programcreek.com/2014/02/leetcode-find-peak-element/
http://algorithms.tutorialhorizon.com/find-a-peak-element-in-a-given-array/

http://www.geeksforgeeks.org/find-a-peak-in-a-given-array/

Friday, March 23, 2012

Find number of occurances of a number

 Given a sorted array with duplicate elements, find the number of occurrences of x.

http://www.geeksforgeeks.org/count-number-of-occurrences-in-a-sorted-array/

Strategy:
We will use the modified binary search to solve this in O(log n) time. Here is the code,

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

int count(int* arr, int x, int start, int end)
{
    if(start > end)
        return 0;

    int mid = (start+end)/2;
    int cnt = 0;

    if(arr[mid] == x)
        cnt = 1 + count(arr, x, start, mid-1) + count(arr, x, mid+1, end);
    else if(arr[mid] > x)
        cnt = count(arr, x, start, mid-1);
    else
        cnt = count(arr, x, mid+1, end);

    return cnt;
}

int main()
{
    int arr[]={1,2,3,3,3,3,3,4};
    int len=sizeof(arr)/sizeof(arr[0]);

    printf("Total count = %d\n", count(arr, 3, 0, len-1));

    return 0;
}

Thursday, March 1, 2012

Floor and Ceiling in a sorted array

Given a sorted array and a value x, the ceiling of x is the smallest element in array greater than or equal to x, and the floor is the greatest element smaller than or equal to x. Assume than the array is sorted in non-decreasing order. Write efficient functions to find floor and ceiling of x.

For example, let the input array be {1, 2, 8, 10, 10, 12, 19}
For x = 0:    floor doesn't exist in array,  ceil  = 1
For x = 1:    floor  = 1,  ceil  = 1
For x = 5:    floor  = 2,  ceil  = 8
For x = 20:   floor  = 19,  ceil doesn't exist in array

http://www.geeksforgeeks.org/search-floor-and-ceil-in-a-sorted-array/

Tuesday, January 10, 2012

Fixed Point in an array such that a[i]=i

Given an array of n distinct integers sorted in ascending order, write a function that returns a Fixed Point in the array, if there is any Fixed Point present in array, else returns -1. Fixed Point in an array is an index i such that arr[i] is equal to i. Note that integers in array can be negative.

Variation:
Find MagickNumber With Duplicate Numbers in Sorted Array 2. Where a magick number is number[i] =i
  -10,-5,2,2,2,2,4,7,9,12,13


Method:
First check whether middle element is Fixed Point or not. If it is, then return it; otherwise check whether index of middle element is greater than value at the index. If index is greater, then Fixed Point(s) lies on the right side of the middle point (obviously only if there is a Fixed Point). Else the Fixed Point(s) lies on left side.

Code:
int binarySearch(int arr[], int low, int high)
{
    if(high >= low)
    {
        int mid = (low + high)/2;  /*low + (high - low)/2;*/
        if(mid == arr[mid])
            return mid;
        if(mid > arr[mid])
            return binarySearch(arr, (mid + 1), high);
        else
            return binarySearch(arr, low, (mid -1));
    }
    /* Return -1 if there is no Fixed Point */
    return -1;
}
int main()
{
    int arr[10] = {-10, -1, 0, 3, 10, 11, 30, 50, 100};
    int n = sizeof(arr)/sizeof(arr[0]);
    printf("Fixed Point is %d", binarySearch(arr, 0, n-1));
    getchar();
    return 0;
}
Time Complexity: O(Logn)

Median of two sorted Arrays

There are 2 sorted arrays A and B of size n each. Write an algorithm to find the median of the array obtained after merging the above 2 arrays(i.e. array of length 2n). The complexity should be O(log(n))

Two Sorted Arrays of Equal Length:
http://www.geeksforgeeks.org/median-of-two-sorted-arrays/

Two Sorted Arrays of Un-Equal Length:
http://www.programcreek.com/2012/12/leetcode-median-of-two-sorted-arrays-java/
http://www.geeksforgeeks.org/median-of-two-sorted-arrays-of-different-sizes/
http://www.leetcode.com/2011/03/median-of-two-sorted-arrays.html

Question on Medians:
1.Find the kth smallest in union of two sorted arrays

www.leetcode.com/2011/01/find-k-th-smallest-element-in-union-of.html

http://anandtechblog.blogspot.in/2011/06/google-interview-find-kth-smallest-from.html

Best Method
Let us first take the k/2th element of both the arrays(say array S1 and S2). If k/2th element of array S1 is greater than the k/2th element of S2 but smaller than (k/2 + 1) element of S2, then k/2th element of array S1 is the answer. (Vice versa is also true)
If k/2th element of S1 is greater than both k/2 and (k/2 + 1) element of S2, then consider 3k/4th (k/2 + k/4) element of S2 and k/4th (k/2-k/4) element of S1 and compare them in the fashion described above(If the element under consideration of one array is greater than the element under consideration of another array but less than the +1 element, then it is the answer).
Each time, increase the pointer of one array by k/(2^i) and decrease the pointer of the other array by k/(2^i) (i is the number of iteration) till the above condition is satisfied.
This way you can find kth element in O(log n) time

Example:
Array S1: 5, 7, 8, 9, 12
Array S2: 3, 10, 11, 14, 15
We need 4th smallest element.
First iteration. 4/2 which is 2nd element of both arrays are considered.
7 < 10 and 8 < 10.
So increase the pointer of S1 by 4/4 ie 3rd position and decrease the pointer of S2 by 4/4 ie 1.
8 > 3 and 8 < 10 and hence 8 is the answer in this case.

Method of Two Pointers:O(n)
int getMedian(int ar1[], int ar2[], int n)
{
  int i = 0;j = 0;count;
  int m1 = -1, m2 = -1;

 for(count = 0; count <= n; count++)
  {
//Case to handle where all elements of one array is smaller than other
    if(i == n)
    {
      m1 = m2;
      m2 = ar2[0];
      break;
    }
   else if(j == n)
    {
      m1 = m2;
      m2 = ar1[0];
      break;
    }

//Actual Comparison
    if(ar1[i] < ar2[j])
    {
      m1 = m2;
      m2 = ar1[i];
      i++;
    }
    else
    {
      m1 = m2;
      m2 = ar2[j];
      j++;
    }

  }   //End of for
  return (m1 + m2)/2;
}

Method of Comparing Medians:O(logn)
int max(int x, int y)
{
    return x > y? x : y;
}
int min(int x, int y)
{
    return x > y? y : x;
}
int median(int arr[], int n)
{
  if(n%2 == 0)
    return (arr[n/2] + arr[n/2-1])/2;
  else
    return arr[n/2];
}

int getMedian(int ar1[], int ar2[], int n)
{
  int m1;
  int m2;

  if(n <= 0)
    return -1;

  if(n == 1)
    return (ar1[0] + ar2[0])/2;

  if (n == 2)
    return (max(ar1[0], ar2[0]) + min(ar1[1], ar2[1])) / 2;

  m1 = median(ar1, n);
  m2 = median(ar2, n);

  if(m1 == m2)
    return m1;

  if (m1 < m2)
    return getMedian(ar1 + n/2, ar2, n - n/2);

  return getMedian(ar2 + n/2, ar1, n - n/2);
}

Method of Binary Search:O(logn)
int getMedianRec(int ar1[], int ar2[], int left, int right, int n)
{
  int i, j;
  /* We have reached at the end (left or right) of ar1[] */
  if(left > right)
    return getMedianRec(ar2, ar1, 0, n-1, n);

  i = (left + right)/2;
  j = n - i - 1;
 /* Recursion terminates here.*/
  if(ar1[i] > ar2[j] && (j == n-1 || ar1[i] <= ar2[j+1]))
  {
     if(ar2[j] > ar1[i-1] || i == 0)
       return (ar1[i] + ar2[j])/2;
     else
       return (ar1[i] + ar1[i-1])/2;
  }

  else if (ar1[i] > ar2[j] && j != n-1 && ar1[i] > ar2[j+1])
    return getMedianRec(ar1, ar2, left, i-1, n);        
  else
    return getMedianRec(ar1, ar2, i+1, right, n);
}

int getMedian(int ar1[], int ar2[], int n)
{
  return getMedianRec(ar1, ar2, 0, n-1, n);
}

Problems on Median of two sorted arrays:
1.Tournament Treehttp://www.geeksforgeeks.org/archives/11556
2.Median in a stream of numbershttp://geeksforgeeks.org/forum/topic/fining-the-median
3.kth smallest in union of two sorted array--http://geeksforgeeks.org/forum/topic/kth-smallest-element-in-the-union-of-the-arrays-in-a-logarithmic-time-algorithm
4.Quick Sort-Suggest a partition approach that reduces worst case complexity to O(n log n)-http://geeksforgeeks.org/forum/topic/quick-sort-in-worst-case-onlogn-1

Tuesday, January 3, 2012

Search an Item in a sorted array with shifted elements

Question 1:
You are given a sorted array with shifted elements. Elements can be shifted to the left or right by 'i' number of places. The sign of 'i' denotes the direction of the shift. For positive 'i' direction of shift is right and left for negative 'i'.

For example, consider the sorted array 2, 3, 4, 8, 10, 11. A shift of 3 places to the right would be denoted by i=2 and the shifted array would look like this: 10, 11, 2, 3, 4, 8,
For i=-2, the shifted array would look like: 4, 8, 10, 11, 2, 3.Search an item 10 in the array.

http://www.geeksforgeeks.org/search-an-element-in-a-sorted-and-pivoted-array/
Question 2:
Find the minimum element in a sorted and rotated array
http://www.geeksforgeeks.org/find-minimum-element-in-a-sorted-and-rotated-array/

Question 3:
Alternatively, Given an array of unsigned integers which is initially increasing and then decreasing find the maximum value in the array
http://www.geeksforgeeks.org/find-the-maximum-element-in-an-array-which-is-first-increasing-and-then-decreasing/

Question 4:
Given a sorted and rotated array, find if there is a pair with a given sum
Given an array that is sorted and then rotated around an unknown point. Find if array has a pair with given sum ‘x’. It may be assumed that all elements in array are distinct.

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


Method 1:Binary Search [ Finding point of rotation ]
Find the pivot point, divide the array in two sub-arrays and call binary search.
The main idea for finding pivot is – for a sorted (in increasing order) and pivoted array, pivot element is the only only element for which next element to it is smaller than it.
OR
1)   Assuming that it is an increasing order sorted array that has been rotated, except for one index A[i] < A[i+1] always holds.

2)   When we pick the middle element, of a such an array, out of the two sub-arrays one will always be in a strictly increasing order.

3)   The point of rotation, would then simply lie in the second sub-array which is not strictly increasing. 

By the virtue of the above mentioned points, whenever we examine the two halves, the starting element will always lie in that half which is not in strictly increasing order. Now once we have decide how to go about doing the binary search, we need to decide what we have to search. We are not directly searching for an number here, but an index i such that A[i] > A[i+1], since this is not possible in a normal sorted array, the index 'i+1' is the pivot of rotation and A[i+1] is the smallest number in the array.

int pivotedBinarySearch(int arr[], int arr_size, int no)
{
   int pivot = findPivot(arr, 0, arr_size-1);
   if(arr[pivot] == no)
     return pivot;
   if(arr[0] <= no)
     return binarySearch(arr, 0, pivot-1, no);
   else
     return binarySearch(arr, pivot+1, arr_size-1, no);
}    


int findPivot(int arr[], int low, int high)
{
   int mid = (low + high)/2;  
   if(arr[mid] > arr[mid + 1])
     return mid;
   if(arr[low] > arr[mid])
     return findPivot(arr, low, mid-1);
   else
     return findPivot(arr, mid + 1, high);
}

Note: If point of rotation is given then we can directly continue with binary search keeping in mind the following point:

// Take care of scenarios where the shift is more
   // than the length of the array
   shift = shift % myArray.Length;

   // -ve shift can be seen as positive shift equal to
   // the length of the array - ( -ve shift)
   if (shift < 0)
       shift = myArray.Length + shift;

Alternatively If we will find Pivot without recursion,
int findSmallest(int* a, int length)
{
    if(length==0 || a==NULL)
        return -1;
         
    int start=0,end=length-1;
     
    while(start <= end)
    {
        int mid=(start+end)/2;
         
        // this is the standard comparison condition
        if(a[mid] > a[mid+1])
            return a[mid+1];
         
        // an extra comparison that adds the optimization that
        // if the mid element is the smallest one, there will not be
        // extra iterations
        if(a[mid] < a[mid-1])
            return a[mid];
             
         
        // the left half is in strictly increasing order
        // so we search in the second half
        if(a[mid] > a[start])
        {
            start = mid+1;
        }
        // The array is not rrotated so we simply
        // return the first element of the array
        else if(a[mid] >= a[start] && a[mid] <= a[end])
             return a[0];
          
        // the right half is in strictly increasing order
        // and hence we will search in the left half
         else
           end= mid-1;
         
    }
    return -1;
}

Time:O(logn)

Method 2:Recursive Without Finding Point of rotation

A sorted array, say: {1,2,3,4,5,6,7,8,9,10,11,12}, do right rotate through carry unknown times, and then it might become: {6,7,8,9,10,11,12,1,2,3,4,5}. Now we need get the index of a given number, say 4, from the array within O(log(n)) time.

We can think of it this way: take the middle element of array, if target is found, fine; if not, and then array become two parts, one is sorted array, the other is shifted sorted array. As illustrated as below diagram:



If the target falls into the sorted array half, we can simple do a binary search; otherwise, repeat this operation in the other half in recursive way. You can see this is divide-and-conquer algorithm. Obviously this is O(log(n)).

//
// A typical binary search implementation
//
int _BinarySearch(unsigned int ShiftedArray[], unsigned int start,unsigned int end, unsigned int target)
{
    // Not found
    if( start == end && ShiftedArray[start] != target) {
       return -1;
    }

    unsigned int middle = start + (end - start)/2;
    if(target == ShiftedArray[middle])
    {
       return middle;
    } else if (target > ShiftedArray[middle]) {
       return _BinarySearch(ShiftedArray, middle + 1, end, target);
    } else {
       return _BinarySearch(ShiftedArray, start, middle - 1, target);
    }
}

//
// Select a given number from shifted array.
// ShiftedArray is something like = {6,7,8,9,10,11,12,1,2,3,4,5}
// If found, return index of the number; if not, reutrn -1
// Require log(N)
//
int SearchShiftedArray(unsigned int ShiftedArray[], unsigned int start,unsigned int end, unsigned int target)
{
    // Start meets end
    if( start == end && ShiftedArray[start] != target) {
       return -1;
    }

    unsigned int middle = start + (end - start)/2;
    if(target == ShiftedArray[middle])
    {
       return middle;
    } 
    else if(ShiftedArray[middle] < ShiftedArray[start]) { // Right half is sorted linearly
       if((target > ShiftedArray[middle]) && (target <= ShiftedArray[end])) {
           return _BinarySearch(ShiftedArray, middle + 1, end, target);
       } else {
           return SearchShiftedArray(ShiftedArray, start, middle-1, target);
       }

    } else { // Left half is sorted linearly
       if((target >= ShiftedArray[start]) && (target < ShiftedArray[middle])) {
           return _BinarySearch(ShiftedArray, start, middle - 1, target);
       } else {
           return SearchShiftedArray(ShiftedArray, middle + 1, end, target);
       }
    }
}


Test cases
Positive: {6,7,8,9,10,11,12,1,2,3,4,5}, target = 3, target = 8
Negative: {6,7,8,9,10,11,12,1,2,3,4,5}, target = 0, target = 13
Boundary: {6,7,8,9,10,11,12,1,2,3,4,5}, target = 6, target = 5
Exceptional: {…max}, target = max

Method 2.2:Iterative without Pivot--Best Method

First, we know that it is a sorted array that’s been rotated. Although we do not know where the rotation pivot is, there is a property we can take advantage of. Here, we make an observation that a rotated array can be classified as two sub-array that is sorted (i.e., 4 5 6 7 0 1 2 consists of two sub-arrays 4 5 6 7 and 0 1 2.
Do not jump to conclusion that we need to first find the location of the pivot and then do binary search on both sub-arrays. Although this can be done in O(lg n) time, this is not necessary and is more complicated.
In fact, we don’t need to know where the pivot is. Look at the middle element (7). Compare it with the left most (4) and right most element (2). The left most element (4) is less than (7). This gives us valuable information — All elements in the bottom half must be in strictly increasing order. Therefore, if the key we are looking for is between 4 and 7, we eliminate the upper half; if not, we eliminate the bottom half.
When left index is greater than right index, we have to stop searching as the key we are finding is not in the array.
Since we reduce the search space by half each time, the complexity must be in the order of O(lg n). It is similar to binary search but is somehow modified for this problem. In fact, this is more general than binary search, as it works for both rotated and non-rotated arrays.
int rotated_binary_search(int A[], int N, int key) {
  int L = 0;
  int R = N - 1;
  while (L <= R) {
    // Avoid overflow, same as M=(L+R)/2
    int M = L + ((R - L) / 2);
    if (A[M] == key) return M;
    // the bottom half is sorted
    if (A[L] <= A[M]) {
      if (A[L] <= key && key < A[M])
        R = M - 1;
      else
        L = M + 1;
    }
    // the upper half is sorted
    else {
      if (A[M] < key && key <= A[R])
        L = M + 1;
      else
        R = M - 1;
    }
  }
  return -1;
}
If we are required to find the rotation point then we can proceed as follows
This problem is in fact the same as finding the minimum element’s index. If the middle element is greater than the right most element, then the pivot must be to the right; if it is not, the pivot must be to the left.
int FindSortedArrayRotation(int A[], int N) {
  int L = 0;
  int R = N - 1;
  while (A[L] > A[R]) {
    int M = L + (R - L) / 2;
    if (A[M] > A[R])
      L = M + 1;
    else
      R = M;
  }
  return L;
}
Useful Link:
http://www.leetcode.com/2010/04/searching-element-in-rotated-array.html
Solution if duplicates are allowed:
#include <iostream>

int rotatedSearch(int values[], int start, int end,int x)
{
    if(values[start] == x){
        return start;
    } else if(values[end] == x){
        return end;
    } else if(end - start == 1) {
        return -1;
    }
    int middle = (start + end) / 2;

    
    if((values[start]==values[middle]) && (values[middle] == values[end]))
        { 
          if((rotatedSearch(values, start, middle, x))!=-1)
              return rotatedSearch(values, start, middle, x);
          else    
               return rotatedSearch(values, middle, end, x);
        }
               
    if(values[start] <= values[middle]){
        if(x <= values[middle] && x >= values[start]){
            return rotatedSearch(values, start, middle, x);
        } else {
            return rotatedSearch(values, middle, end, x);
        }
    } else if(values[middle] <= values[end]){
        if(x >= values[middle] && x <= values[end] ){
            return rotatedSearch(values, middle, end, x);
        } else {
            return rotatedSearch(values, start, middle, x);
        }
    } else {
        return -1;
    }
}

int main()
{
 //  int arr[12] = {1, 2, 2, 3, 4, 5, 6, 7, 1, 1, 1, 1};
   int arr[13] = {1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1};
  //int arr[13] = {1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1};
   printf("Index of the element is %d", rotatedSearch(arr, 0,11, 2)); 
   getchar();
   return 0;
}

Question 2:Modified Binary Search to find maximum element
int search(int* arr, int strt, int end)
{
    int mid = (strt+end)/2;

    if((arr[mid-1] < arr[mid]) &&  (arr[mid] > arr[mid+1]))
        return arr[mid];
    else if(arr[mid-1] < arr[mid])
        return search(arr, mid+1, end);
    else if(arr[mid] > arr[mid+1])
        return search(arr, strt, mid-1);
}

int main()
{
    int arr[10] = {1, 2, 3, 4, 5, 6, 7, 6, 5, 4};

    printf("%d\n", search(arr, 0, 9));
    return 0;
}