Find an element in Bitonic array - GeeksforGeeks

04 Mar, 2022
Given a bitonic sequence of n distinct elements, and an integer x, the task is to write a program to find given element x in the bitonic sequence in O(log n) time. 
A Bitonic Sequence is a sequence of numbers that is first strictly increasing then after a point decreasing.
Examples: 
Input :  arr[] = {-3, 9, 18, 20, 17, 5, 1}, key = 20Output : Found at index 3
Input :  arr[] = {5, 6, 7, 8, 9, 10, 3, 2, 1}, key = 30Output : Not Found
Naive Approach: A simple solution is to do a linear search. The time complexity of this solution would be O(n).
Efficient Approach: 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 a given sequence. 
If the element to be searched is greater than the maximum element return -1, 
else search the element in both halves. 
Below is the step by step algorithm on how to do this.
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.If the element to be searched is equal to the element at the bitonic point then print the index of the bitonic point.If the element to be searched is greater than the element at a bitonic point then the element does not exist in the array.If the element to be searched is less than the element at a bitonic point then search for the element in both halves of the array using binary search.
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.
If the element to be searched is equal to the element at the bitonic point then print the index of the bitonic point.
If the element to be searched is greater than the element at a bitonic point then the element does not exist in the array.
If the element to be searched is less than the element at a bitonic point then search for the element in both halves of the array using binary search.
Below is the implementation of the above idea: 
C++
Java
Python3
C#
Javascript
// C++ code to search key in bitonic array#include <iostream> using namespace std; // Function for binary search in ascending partint 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 arrayint 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 pointint findBitonicPoint(int arr[], int n,                    int l, int r){    int mid;    int bitonicPoint = 0;    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])    {        bitonicPoint = findBitonicPoint(arr, n, mid, r);    }     else if (arr[mid] < arr[mid - 1]            && arr[mid] > arr[mid + 1])    {        bitonicPoint = findBitonicPoint(arr, n, l, mid);    }    return bitonicPoint;} // Function to search key in// bitonic arrayint 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 codeint 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;     // Function call    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;}
// Java code to search key in bitonic arraypublic 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;        int bitonicPoint = 0;        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])            {                bitonicPoint = findBitonicPoint(arr, n, mid, r);            }            else {                if (arr[mid] < arr[mid - 1]                    && arr[mid] > arr[mid + 1])                {                    bitonicPoint = findBitonicPoint(arr, n, l, mid);                }            }        }        return bitonicPoint;    }     // 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    public static void main(String args[])    {        int arr[] = { -8, 1, 2, 3, 4, 5, -2, -3 };        int key = 5;        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*/
# Python code to search key in bitonic array # Function for binary search in ascending partdef ascendingBinarySearch(arr, low, high, key):         while low <= high:        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 arraydef descendingBinarySearch(arr, low, high, key):         while low <= high:        mid = low + (high - low) // 2                 if arr[mid] == key:            return mid                 if arr[mid] < key:            high = mid - 1        else:            low = mid + 1                 return -1 # Find bitonic pointdef findBitonicPoint(arr, n, l, r):         bitonicPoint = 0    mid = (r + l) // 2         if arr[mid] > arr[mid-1] and arr[mid] > arr[mid+1]:        return mid         elif arr[mid] > arr[mid-1] and arr[mid] < arr[mid+1]:        bitonicPoint = findBitonicPoint(arr, n, mid, r)    else:        bitonicPoint = finsBitonicPoint(arr, n, l, mid)             return bitonicPoint # Function to search key in bitonic arraydef searchBitonic(arr, n, key, index):         if key > arr[index]:        return -1    elif key == arr[index]:        return index    else:        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 codedef main():    arr = [-8, 1, 2, 3, 4, 5, -2, -3]    key = 1    n = len(arr)    l = 0    r = n - 1         # Function call    index = findBitonicPoint(arr, n, l, r)         x = searchBitonic(arr, n, key, index)         if x == -1:        print("Element Not Found")    else:        print("Element Found at index", x)         main() # This code is contributed by stutipathak31jan
// C# code to search key in bitonic arrayusing 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;        int bitonicPoint = 0;        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]) {                bitonicPoint = findBitonicPoint(arr, n, mid, r);            }            else            {                if (arr[mid] < arr[mid - 1]                    && arr[mid] > arr[mid + 1]) {                    bitonicPoint = findBitonicPoint(arr, n, l, mid);                }            }        }        return bitonicPoint;    }     // 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
<script> // JavaScript code to search key in bitonic array  // Function for binary search in ascending partfunction ascendingBinarySearch(arr, low, high, key) {    while (low <= high) {        let mid = Math.floor(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 arrayfunction descendingBinarySearch(arr, low, high, key) {    while (low <= high) {        let mid = Math.floor(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 pointfunction findBitonicPoint(arr, n, l, r) {    let mid;    let bitonicPoint = 0;    mid = Math.floor((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]) {        bitonicPoint = findBitonicPoint(arr, n, mid, r);    }     else if (arr[mid] < arr[mid - 1]        && arr[mid] > arr[mid + 1]) {        bitonicPoint = findBitonicPoint(arr, n, l, mid);    }    return bitonicPoint;} // Function to search key in// bitonic arrayfunction searchBitonic(arr, n, key, index) {    if (key > arr[index])        return -1;     else if (key == arr[index])        return index;     else {        let 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 let arr = [-8, 1, 2, 3, 4, 5, -2, -3];let key = 1;let n, l, r;n = arr.length;l = 0;r = n - 1;let index; // Function callindex = findBitonicPoint(arr, n, l, r); let x = searchBitonic(arr, n, key, index); if (x == -1)    document.write("Element Not Found" + "<br>");else    document.write("Element Found at index " + x + "<br>");     </script>
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 write.geeksforgeeks.org or mail your article to review-team@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. 
29AjayKumar
jit_t
shresth_mehta
guptarashi2001
prajjwal21
stutipathak31jan
_saurabh_jaiswal
ankit1210
nehakumariintern
Binary Search
Arrays
Arrays
Binary Search
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Maximum and minimum of an array using minimum number of comparisons
Top 50 Array Coding Problems for Interviews
Stack Data Structure (Introduction and Program)
Introduction to Arrays
Multidimensional Arrays in Java
Linear Search
Linked List vs Array
Python | Using 2D arrays/lists the right way
Search an element in a sorted and rotated array
Array of Strings in C++ (5 Different Ways to Create)