Search for an element in a Mountain Array

31 May, 2021
Given a mountain array arr[] and an integer X, the task is to find the smallest index of X in the given array. If no such index is found, print -1.
Examples:
Input: arr = {1, 2, 3, 4, 5, 3, 1}, X = 3Output: 2Explanation: The smallest index of X(= 3) in the array is 2. Therefore, the required output is 2.
Input: arr[] = {0, 1, 2, 4, 2, 1}, X = 3Output: -1Explanation: Since 3 does not exist in the array, the required output is -1.
Naive Approach: The simplest approach is to traverse the array and check if the element in the current index is equal to X or not. If found to be true, then print that index. 
Time Complexity: O(N)Auxiliary Space: O(1)
Efficient Approach: The optimal idea to solve this problem is to use Binary Search. Follow the steps below to solve this problem:
Find the peak index from the mountain array.
Based on the obtained peak index, the partition array into two parts. It searches for its left side first using Binary search, followed by its right. It is known that the left side of the peak element is sorted in ascending order and the right side is sorted in descending order.
Search in the left mountain array.
Below is the implementation of the above approach:
C++
Java
Python3
C#
Javascript
// CPP program for the above approach#include<bits/stdc++.h>using namespace std; // Function to find the index of// the peak element in the arrayint findPeak(vector<int> arr){   // Stores left most index in which  // the peak element can be found  int left = 0;   // Stores right most index in which  // the peak element can be found  int right = arr.size() - 1;  while (left < right)  {     // Stores mid of left and right    int mid = left + (right - left) / 2;     // If element at mid is less than    // element at (mid + 1)    if (arr[mid] < arr[mid + 1])    {       // Update left      left = mid + 1;    }    else    {       // Update right      right = mid;    }  }  return left;} // Function to perform binary search in an// a subarray if elements of the subarray// are in an ascending orderint BS(int X, int left, int right,       vector<int> arr){  while (left <= right)  {     // Stores mid of left and right    int mid = left + (right - left) / 2;     // If X found at mid    if (arr[mid] == X)    {      return mid;    }     // If X is greater than mid    else if (X > arr[mid])    {       // Update left      left = mid + 1;    }     else    {       // Update right      right = mid - 1;    }  }  return -1;} // Function to perform binary search in an// a subarray if elements of the subarray// are in an ascending orderint reverseBS(int X, int left, int right, vector<int> arr){  while (left <= right)  {     // Stores mid of left and right    int mid = left + (right - left) / 2;     // If X found at mid    if (arr[mid] == X)    {      return mid;    }     else if (X > arr[mid])    {       // Update right      right = mid - 1;    }    else    {       // Update left      left = mid + 1;    }  }  return -1;} // Function to find the smallest index of Xvoid findInMA(int X, vector<int> mountainArr){   // Stores index of peak element in array  int peakIndex = findPeak(mountainArr);   // Stores index of X in the array  int res = -1;   // If X greater than or equal to first element  // of array and less than the peak element  if (X >= mountainArr[0] && X <= mountainArr[peakIndex])  {     // Update res    res = BS(X, 0, peakIndex, mountainArr);  }   // If element not found on  // left side of peak element  if (res == -1)  {     // Update res    res = reverseBS(X, peakIndex + 1,                    mountainArr.size() - 1,                    mountainArr);  }   // Print res  cout<<res<<endl;} // Driver Codeint main(){   // Given X  int X = 3;   // Given array  vector<int> list{1, 2, 3, 4, 5, 3, 1};   // Function Call  findInMA(X, list);} // This code is contributed by bgangwar59.
// Java program for the above approach import java.io.*;import java.util.*; class GFG {     // Function to find the index of    // the peak element in the array    public static int findPeak(        ArrayList<Integer> arr)    {         // Stores left most index in which        // the peak element can be found        int left = 0;         // Stores right most index in which        // the peak element can be found        int right = arr.size() - 1;         while (left < right) {             // Stores mid of left and right            int mid = left + (right - left) / 2;             // If element at mid is less than            // element at (mid + 1)            if (arr.get(mid) < arr.get(mid + 1)) {                 // Update left                left = mid + 1;            }            else {                 // Update right                right = mid;            }        }         return left;    }     // Function to perform binary search in an    // a subarray if elements of the subarray    // are in an ascending order    static int BS(int X, int left, int right,                  ArrayList<Integer> arr)    {         while (left <= right) {             // Stores mid of left and right            int mid = left + (right - left) / 2;             // If X found at mid            if (arr.get(mid) == X) {                return mid;            }             // If X is greater than mid            else if (X > arr.get(mid)) {                 // Update left                left = mid + 1;            }             else {                 // Update right                right = mid - 1;            }        }        return -1;    }     // Function to perform binary search in an    // a subarray if elements of the subarray    // are in an ascending order    static int reverseBS(int X, int left, int right,                         ArrayList<Integer> arr)    {        while (left <= right) {             // Stores mid of left and right            int mid = left + (right - left) / 2;             // If X found at mid            if (arr.get(mid) == X) {                return mid;            }             else if (X > arr.get(mid)) {                 // Update right                right = mid - 1;            }            else {                 // Update left                left = mid + 1;            }        }        return -1;    }     // Function to find the smallest index of X    static void findInMA(int X,                         ArrayList<Integer> mountainArr)    {         // Stores index of peak element in array        int peakIndex = findPeak(mountainArr);         // Stores index of X in the array        int res = -1;         // If X greater than or equal to first element        // of array and less than the peak element        if (X >= mountainArr.get(0)            && X <= mountainArr.get(peakIndex)) {             // Update res            res = BS(X, 0, peakIndex, mountainArr);        }         // If element not found on        // left side of peak element        if (res == -1) {             // Update res            res = reverseBS(X, peakIndex + 1,                            mountainArr.size() - 1,                            mountainArr);        }         // Print res        System.out.println(res);    }     // Driver Code    public static void main(String[] args)    {         // Given X        int X = 3;         // Given array        ArrayList<Integer> list = new ArrayList<>(            Arrays.asList(1, 2, 3, 4, 5, 3, 1));         // Function Call        findInMA(X, list);    }}
# Python3 program for the above approach # Function to find the index of# the peak element in the arraydef findPeak(arr):         # Stores left most index in which    # the peak element can be found    left = 0     # Stores right most index in which    # the peak element can be found    right = len(arr) - 1     while (left < right):         # Stores mid of left and right        mid = left + (right - left) // 2         # If element at mid is less than        # element at(mid + 1)        if (arr[mid] < arr[(mid + 1)]):             # Update left            left = mid + 1         else:             # Update right            right = mid     return left # Function to perform binary search in an# a subarray if elements of the subarray# are in an ascending orderdef BS(X, left, right, arr):         while (left <= right):         # Stores mid of left and right        mid = left + (right - left) // 2         # If X found at mid        if (arr[mid] == X):            return mid         # If X is greater than mid        elif (X > arr[mid]):             # Update left            left = mid + 1         else:             # Update right            right = mid - 1     return -1 # Function to perform binary search in an# a subarray if elements of the subarray# are in an ascending orderdef reverseBS(X, left, right, arr):         while (left <= right):         # Stores mid of left and right        mid = left + (right - left) // 2         # If X found at mid        if (arr[mid] == X):            return mid         elif (X > arr[mid]):             # Update right            right = mid - 1         else:                         # Update left            left = mid + 1                 return -1 # Function to find the smallest index of Xdef findInMA(X, mountainArr):         # Stores index of peak element in array    peakIndex = findPeak(mountainArr)     # Stores index of X in the array    res = -1     # If X greater than or equal to first element    # of array and less than the peak element    if (X >= mountainArr[0] and        X <= mountainArr[peakIndex]):         # Update res        res = BS(X, 0, peakIndex, mountainArr)     # If element not found on    # left side of peak element    if (res == -1):         # Update res        res = reverseBS(X, peakIndex + 1,                        mountainArr.size() - 1,                        mountainArr)     # Print res    print(res) # Driver Codeif __name__ == "__main__":     # Given X    X = 3     # Given array    arr = [ 1, 2, 3, 4, 5, 3, 1 ]     # Function Call    findInMA(X, arr) # This code is contributed by chitranayal
// C# program for the above approachusing System;using System.Collections.Generic;using System.Linq;class GFG{     // Function to find the index of    // the peak element in the array    public static int findPeak(List<int> arr)    {         // Stores left most index in which        // the peak element can be found        int left = 0;         // Stores right most index in which        // the peak element can be found        int right = arr.Count - 1;         while (left < right)        {             // Stores mid of left and right            int mid = left + (right - left) / 2;             // If element at mid is less than            // element at (mid + 1)            if (arr[mid] < arr[(mid + 1)])            {                 // Update left                left = mid + 1;            }            else            {                 // Update right                right = mid;            }        }         return left;    }     // Function to perform binary search in an    // a subarray if elements of the subarray    // are in an ascending order    static int BS(int X, int left, int right,                List<int> arr)    {         while (left <= right)        {             // Stores mid of left and right            int mid = left + (right - left) / 2;             // If X found at mid            if (arr[(mid)] == X)            {                return mid;            }             // If X is greater than mid            else if (X > arr[mid])            {                 // Update left                left = mid + 1;            }             else            {                 // Update right                right = mid - 1;            }        }        return -1;    }     // Function to perform binary search in an    // a subarray if elements of the subarray    // are in an ascending order    static int reverseBS(int X, int left, int right,                         List<int> arr)    {        while (left <= right)        {             // Stores mid of left and right            int mid = left + (right - left) / 2;             // If X found at mid            if (arr[mid] == X)            {                return mid;            }             else if (X > arr[mid])            {                 // Update right                right = mid - 1;            }            else            {                 // Update left                left = mid + 1;            }        }        return -1;    }     // Function to find the smallest index of X    static void findInMA(int X,                         List<int> mountainArr)    {         // Stores index of peak element in array        int peakIndex = findPeak(mountainArr);         // Stores index of X in the array        int res = -1;         // If X greater than or equal to first element        // of array and less than the peak element        if (X >= mountainArr[0]            && X <= mountainArr[peakIndex])        {             // Update res            res = BS(X, 0, peakIndex, mountainArr);        }         // If element not found on        // left side of peak element        if (res == -1)        {             // Update res            res = reverseBS(X, peakIndex + 1,                            mountainArr.Count - 1,                            mountainArr);        }         // Print res        Console.WriteLine(res);    }     // Driver Code    public static void Main( )    {         // Given X        int X = 3;         // Given array        List<int> list =  new List<int>(){1, 2, 3, 4, 5, 3, 1};         // Function Call        findInMA(X, list);    }} // This code is contributed by code_hunt.
<script> // Javascript program for the above approach // Function to find the index of// the peak element in the arrayfunction findPeak(arr){   // Stores left most index in which  // the peak element can be found  var left = 0;   // Stores right most index in which  // the peak element can be found  var right = arr.length - 1;  while (left < right)  {     // Stores mid of left and right    var mid = left + parseInt((right - left) / 2);     // If element at mid is less than    // element at (mid + 1)    if (arr[mid] < arr[mid + 1])    {       // Update left      left = mid + 1;    }    else    {       // Update right      right = mid;    }  }  return left;} // Function to perform binary search in an// a subarray if elements of the subarray// are in an ascending orderfunction BS(X, left, right, arr){  while (left <= right)  {     // Stores mid of left and right    var mid = left + parseInt((right - left) / 2);     // If X found at mid    if (arr[mid] == X)    {      return mid;    }     // If X is greater than mid    else if (X > arr[mid])    {       // Update left      left = mid + 1;    }     else    {       // Update right      right = mid - 1;    }  }  return -1;} // Function to perform binary search in an// a subarray if elements of the subarray// are in an ascending orderfunction reverseBS(X, left, right, arr){  while (left <= right)  {     // Stores mid of left and right    var mid = left + parseInt((right - left) / 2);     // If X found at mid    if (arr[mid] == X)    {      return mid;    }     else if (X > arr[mid])    {       // Update right      right = mid - 1;    }    else    {       // Update left      left = mid + 1;    }  }  return -1;} // Function to find the smallest index of Xfunction findInMA(X, mountainArr){   // Stores index of peak element in array  var peakIndex = findPeak(mountainArr);   // Stores index of X in the array  var res = -1;   // If X greater than or equal to first element  // of array and less than the peak element  if (X >= mountainArr[0] && X <= mountainArr[peakIndex])  {     // Update res    res = BS(X, 0, peakIndex, mountainArr);  }   // If element not found on  // left side of peak element  if (res == -1)  {     // Update res    res = reverseBS(X, peakIndex + 1,                    mountainArr.length - 1,                    mountainArr);  }   // Print res  document.write( res + "<br>");} // Driver Code// Given Xvar X = 3;// Given arrayvar list = [1, 2, 3, 4, 5, 3, 1];// Function CallfindInMA(X, list); </script>
2
 
Time Complexity: O(Log(N))Auxiliary Space: O(1)
code_hunt
ukasp
bgangwar59
importantly
Algorithms-Divide and Conquer
Binary Search
Arrays
Divide and Conquer
Searching
Sorting
Arrays
Searching
Divide and Conquer
Sorting
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
Multidimensional Arrays in Java
Stack Data Structure (Introduction and Program)
Linear Search
Merge Sort
QuickSort
Binary Search
Maximum and minimum of an array using minimum number of comparisons
Count Inversions in an array | Set 1 (Using Merge Sort)