Find an element in Bitonic array

Given a bitonic sequence of n distinct elements, write a program to find a given element x in the bitonic sequence in O(log n) time. A Bitonic Sequence is a sequence of numbers which is first strictly increasing then after a point strictly decreasing.

Examples:

Input :  arr[] = {-3, 9, 8, 20, 17, 5, 1};
         key = 20
Output : Found at index 3

Input :  arr[] = {5, 6, 7, 8, 9, 10, 1, 2, 3};
         key = 30
Output : Not Found 

A simple solution is to do linear search. Time complexity of this solution would be O(n).



An efficient solution is based on Binary Search. The idea is to find the bitonic point k which is the index of the maximum element of given sequence. If the element to be searched is greater than maximum element return -1, else search the element in both halves. Below is the step by step algorithm on how to do this.

  1. Find the bitonic point in the given array, i.e the maximum element in the given bitonic array. This can be done in log(n) time by modifying the binary search algorithm. You can refer to this post on how to do this.
  2. If the element to be searched is equal to the element at bitonic point then print the index of bitonic point.
  3. If the element to be searched is greater than element at bitonic point then element does not exist in the array.
  4. If the element to be searched is less than element at bitonic point then search for element in both half of the array using binary search.

Below is the implementation of above idea:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// CPP code to search key in bitonic array
#include <iostream>
  
using namespace std;
  
// Function for binary search in ascending part
int ascendingBinarySearch(int arr[], int low,
                           int high, int key)
{
   while (low <= high)
   {
       int mid = low + (high - low) / 2;
       if (arr[mid] == key)
           return mid;
       if (arr[mid] > key)
           high = mid - 1;
       else
           low = mid + 1;
   }
    return -1;
}
  
// Function for binary search in descending part of array
int descendingBinarySearch(int arr[], int low, 
                            int high, int key)
{
   while (low <= high)
   {
       int mid = low + (high - low) / 2;
       if (arr[mid] == key)
           return mid;
       if (arr[mid] < key)
           high = mid - 1;
       else
           low = mid + 1;
   }
    return -1;
}
   
// finding bitonic point
int findBitonicPoint(int arr[] ,int n, int l, int r )
{
    int mid;
      
    mid = (r + l) / 2;
    if(arr[mid] > arr[mid-1] && arr[mid] > arr[mid + 1])
    {
        return mid;
    }
      
    else 
    if(arr[mid] > arr[mid - 1] && arr[mid] < arr[mid + 1])
    {
        findBitonicPoint(arr,n, mid , r);
    }
  
    else 
    if(arr[mid] < arr[mid - 1] && arr[mid] > arr[mid + 1])
    {
        findBitonicPoint(arr, n, l, mid);
    }
}
  
// Function to search key in bitonic array
int searchBitonic(int arr[], int n, int key, int index)
{
    if(key > arr[index])
        return -1;
      
    else if(key == arr[index])
        return index;
      
    else
    {    int temp = ascendingBinarySearch(arr, 0, index - 1, key);
        if (temp != -1)
        {
             return temp;
        }
          
        // Search in right of k
        return descendingBinarySearch(arr, index + 1, n - 1, key);
    }
}
  
// Driver code
int main() {
    int arr[] = {-8, 1, 2, 3, 4, 5, -2, -3};
    int key = 1;
    int n ,l, r;
    n = sizeof(arr)/sizeof(arr[0]);
    l = 0;
    r = n - 1;
    int index;
    index = findBitonicPoint(arr, n, l, r);
       
    int x = searchBitonic(arr, n, key, index);
      
    if (x == -1)
       cout << "Element Not Found"<<endl;
    else
       cout << "Element Found at index " << x<<endl;
      
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java code to search key in bitonic array
  
public class GFG {
  
// CPP code to search key in bitonic array 
// Function for binary search in ascending part 
    static int ascendingBinarySearch(int arr[], int low,
            int high, int key) {
        while (low <= high) {
            int mid = low + (high - low) / 2;
            if (arr[mid] == key) {
                return mid;
            }
            if (arr[mid] > key) {
                high = mid - 1;
            } else {
                low = mid + 1;
            }
        }
        return -1;
    }
  
// Function for binary search in descending part of array 
    static int descendingBinarySearch(int arr[], int low,
            int high, int key) {
        while (low <= high) {
            int mid = low + (high - low) / 2;
            if (arr[mid] == key) {
                return mid;
            }
            if (arr[mid] < key) {
                high = mid - 1;
            } else {
                low = mid + 1;
            }
        }
        return -1;
    }
  
// finding bitonic point 
    static int findBitonicPoint(int arr[], int n, int l, int r) {
        int mid;
  
        mid = (r + l) / 2;
        if (arr[mid] > arr[mid - 1] && arr[mid] > arr[mid + 1]) {
            return mid;
        } else {
            if (arr[mid] > arr[mid - 1] && arr[mid] < arr[mid + 1]) {
                findBitonicPoint(arr, n, mid, r);
            } else {
                if (arr[mid] < arr[mid - 1] && arr[mid] > arr[mid + 1]) {
                    findBitonicPoint(arr, n, l, mid);
                }
            }
        }
        return mid;
    }
  
// Function to search key in bitonic array 
    static int searchBitonic(int arr[], int n, int key, int index) {
        if (key > arr[index]) {
            return -1;
        } else if (key == arr[index]) {
            return index;
        } else {
            int temp = ascendingBinarySearch(arr, 0, index - 1, key);
            if (temp != -1) {
                return temp;
            }
  
            // Search in right of k 
            return descendingBinarySearch(arr, index + 1, n - 1, key);
        }
    }
  
// Driver program to test above function 
    public static void main(String args[]) {
        int arr[] = {-8, 1, 2, 3, 4, 5, -2, -3};
        int key = 1;
        int n, l, r;
        n = arr.length;
        l = 0;
        r = n - 1;
        int index;
        index = findBitonicPoint(arr, n, l, r);
  
        int x = searchBitonic(arr, n, key, index);
  
        if (x == -1) {
            System.out.println("Element Not Found");
        } else {
            System.out.println("Element Found at index " + x);
        }
  
    }
}
  
/*This code is contributed by 29AjayKumar*/

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# code to search key in bitonic array
using System;
  
class GFG
{
// Function for binary search in ascending part 
static int ascendingBinarySearch(int []arr, int low,
                                 int high, int key) 
{
    while (low <= high) 
    {
        int mid = low + (high - low) / 2;
        if (arr[mid] == key) 
        {
            return mid;
        }
        if (arr[mid] > key) 
        {
            high = mid - 1;
        }
        else
        {
            low = mid + 1;
        }
    }
    return -1;
}
  
// Function for binary search in descending part of array 
static int descendingBinarySearch(int []arr, int low,
                                  int high, int key) 
{
    while (low <= high) 
    {
        int mid = low + (high - low) / 2;
        if (arr[mid] == key) 
        {
            return mid;
        }
        if (arr[mid] < key) 
        {
            high = mid - 1;
        
        else 
        {
            low = mid + 1;
        }
    }
    return -1;
}
  
// finding bitonic point 
static int findBitonicPoint(int []arr, int n, 
                            int l, int r) 
{
    int mid;
  
    mid = (r + l) / 2;
    if (arr[mid] > arr[mid - 1] && 
        arr[mid] > arr[mid + 1])
    {
        return mid;
    
    else 
    {
        if (arr[mid] > arr[mid - 1] && 
            arr[mid] < arr[mid + 1]) 
        {
            findBitonicPoint(arr, n, mid, r);
        }
        else 
        {
            if (arr[mid] < arr[mid - 1] && 
                arr[mid] > arr[mid + 1]) 
            {
                findBitonicPoint(arr, n, l, mid);
            }
        }
    }
    return mid;
}
  
// Function to search key in bitonic array 
static int searchBitonic(int []arr, int n, 
                         int key, int index) 
{
    if (key > arr[index]) 
    {
        return -1;
    
    else if (key == arr[index]) 
    {
        return index;
    }
    else 
    {
        int temp = ascendingBinarySearch(arr, 0, 
                                         index - 1, key);
        if (temp != -1) 
        {
            return temp;
        }
  
        // Search in right of k 
        return descendingBinarySearch(arr, index + 1, 
                                      n - 1, key);
    }
}
  
// Driver Code
static public void Main ()
{
    int []arr = {-8, 1, 2, 3, 4, 5, -2, -3};
    int key = 1;
    int n, l, r;
    n = arr.Length;
    l = 0;
    r = n - 1;
    int index;
    index = findBitonicPoint(arr, n, l, r);
  
    int x = searchBitonic(arr, n, key, index);
  
    if (x == -1) 
    {
        Console.WriteLine("Element Not Found");
    
    else
    {
        Console.WriteLine("Element Found at index " + x);
    }
}
}
  
// This code is contributed by ajit

chevron_right



Output:

Element Found at index 1

Time complexity: O(log n)
Auxiliary Space: O(1)
This article is contributed by Vaishali Goyal. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.



My Personal Notes arrow_drop_up

Improved By : 29AjayKumar, jit_t



Article Tags :
Practice Tags :


6


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.