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:
- 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:
// 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 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 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# 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. |
<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> |
2
Time Complexity: O(Log(N))
Auxiliary Space: O(1)