Open In App

Search for an element in a Mountain Array

Improve
Improve
Like Article
Like
Save
Share
Report

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 = 3
Output: 2
Explanation: 
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 = 3
Output: -1
Explanation: 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:

Below is the implementation of the above approach:

C++




// CPP program for the above approach
#include<bits/stdc++.h>
using namespace std;
 
// Function to find the index of
// the peak element in the array
int 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 order
int 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 descending order
int 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 X
void 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 Code
int 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




// 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 descending 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




# Python3 program for the above approach
 
# Function to find the index of
# the peak element in the array
def 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 order
def 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 descending order
def 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 X
def 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 Code
if __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#




// C# program for the above approach
using 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 descending 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.


Javascript




<script>
 
// Javascript program for the above approach
 
// Function to find the index of
// the peak element in the array
function 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 order
function 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 descending order
function 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 X
function 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 X
var X = 3;
// Given array
var list = [1, 2, 3, 4, 5, 3, 1];
// Function Call
findInMA(X, list);
 
</script>


Output: 

2

 

Time Complexity: O(Log(N))
Auxiliary Space: O(1)



Last Updated : 02 Aug, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads