Open In App

Search for an element in a Mountain Array

Last Updated : 02 Aug, 2022
Comments
Improve
Suggest changes
Like Article
Like
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)


Next Article

Similar Reads