Given an array arr[0 .. n-1] of distinct integers, the task is to find a local minimum in it. We say that an element arr[x] is a local minimum if it is less than both its neighbors.
- For corner elements, we need to consider only one neighbor for comparison.
- There can be more than one local minima in an array, we need to find one of them.
Examples:
Input: arr[] = {9, 6, 3, 14, 5, 7, 4};
Output: Index of local minima is 2
The output prints index of 3 because it is
smaller than both of its neighbors.
Note that indexes of elements 5 and 4 are
also valid outputs.
Input: arr[] = {23, 8, 15, 2, 3};
Output: Index of local minima is 1
Input: arr[] = {1, 2, 3};
Output: Index of local minima is 0
Input: arr[] = {3, 2, 1};
Output: Index of local minima is 2
A simple solution is to do a linear scan of array and as soon as we find a local minima, we return it. The worst case time complexity of this method would be O(n).
An efficient solution is based on Binary Search. We compare middle element with its neighbors. If middle element is not greater than any of its neighbors, then we return it. If the middle element is greater than its left neighbor, then there is always a local minima in left half (Why? take few examples). If the middle element is greater than its right neighbor, then there is always a local minima in right half (due to same reason as left half).
Below is the implementation of the above idea :
C++
#include <stdio.h>
int localMinUtil( int arr[], int low, int high, int n)
{
int mid = low + (high - low)/2;
if ((mid == 0 || arr[mid-1] > arr[mid]) &&
(mid == n-1 || arr[mid+1] > arr[mid]))
return mid;
else if (mid > 0 && arr[mid-1] < arr[mid])
return localMinUtil(arr, low, (mid -1), n);
return localMinUtil(arr, (mid + 1), high, n);
}
int localMin( int arr[], int n)
{
return localMinUtil(arr, 0, n-1, n);
}
int main()
{
int arr[] = {4, 3, 1, 14, 16, 40};
int n = sizeof (arr)/ sizeof (arr[0]);
printf ( "Index of a local minima is %d" ,
localMin(arr, n));
return 0;
}
|
Java
import java.io.*;
class GFG
{
public static int localMinUtil( int [] arr, int low,
int high, int n)
{
int mid = low + (high - low) / 2 ;
if (mid == 0 || arr[mid - 1 ] > arr[mid] && mid == n - 1 ||
arr[mid] < arr[mid + 1 ])
return mid;
else if (mid > 0 && arr[mid - 1 ] < arr[mid])
return localMinUtil(arr, low, mid - 1 , n);
return localMinUtil(arr, mid + 1 , high, n);
}
public static int localMin( int [] arr, int n)
{
return localMinUtil(arr, 0 , n - 1 , n);
}
public static void main (String[] args)
{
int arr[] = { 4 , 3 , 1 , 14 , 16 , 40 };
int n = arr.length;
System.out.println( "Index of a local minima is " + localMin(arr, n));
}
}
|
Python3
def localMinUtil(arr, low, high, n):
mid = low + (high - low) / / 2
if ((mid = = 0 or arr[mid - 1 ] > arr[mid]) and
(mid = = n - 1 or arr[mid + 1 ] > arr[mid])):
return mid
elif (mid > 0 and arr[mid - 1 ] < arr[mid]):
return localMinUtil(arr, low, (mid - 1 ), n)
return localMinUtil(arr, (mid + 1 ), high, n)
def localMin(arr, n):
return localMinUtil(arr, 0 , n - 1 , n)
if __name__ = = '__main__' :
arr = [ 4 , 3 , 1 , 14 , 16 , 40 ]
n = len (arr)
print ( "Index of a local minima is" , localMin(arr, n))
|
C#
using System;
class GFG
{
public static int localMinUtil( int [] arr, int low,
int high, int n)
{
int mid = low + (high - low) / 2;
if (mid == 0 || arr[mid - 1] > arr[mid] &&
mid == n - 1 || arr[mid] < arr[mid + 1])
return mid;
else if (mid > 0 && arr[mid - 1] < arr[mid])
return localMinUtil(arr, low, mid - 1, n);
return localMinUtil(arr, mid + 1, high, n);
}
public static int localMin( int [] arr, int n)
{
return localMinUtil(arr, 0, n - 1, n);
}
public static void Main ()
{
int []arr = {4, 3, 1, 14, 16, 40};
int n = arr.Length;
Console.WriteLine( "Index of a local minima is " +
localMin(arr, n));
}
}
|
PHP
<?php
function localMinUtil( $arr , $low , $high , $n )
{
$mid = $low + ( $high - $low ) / 2;
if (( $mid == 0 or $arr [ $mid - 1] > $arr [ $mid ]) and
( $mid == $n - 1 or $arr [ $mid + 1] > $arr [ $mid ]))
return $mid ;
else if ( $mid > 0 and $arr [ $mid - 1] < $arr [ $mid ])
return localMinUtil( $arr , $low , ( $mid - 1), $n );
return localMinUtil(arr, (mid + 1), high, n);
}
function localMin( $arr , $n )
{
return floor (localMinUtil( $arr , 0, $n - 1, $n ));
}
$arr = array (4, 3, 1, 14, 16, 40);
$n = count ( $arr );
echo "Index of a local minima is " ,
localMin( $arr , $n );
?>
|
Javascript
function localMinUtil(arr, low, high ,n)
{
let mid = Math.trunc(low + (high - low) / 2);
if (mid == 0 || arr[mid - 1] > arr[mid] && mid == n - 1 ||
arr[mid] < arr[mid + 1])
return mid;
else if (mid > 0 && arr[mid - 1] < arr[mid])
return localMinUtil(arr, low, mid - 1, n);
return localMinUtil(arr, mid + 1, high, n);
}
function localMin(arr, n){
return localMinUtil(arr, 0, n-1, n);
}
let arr = [ 4, 3, 1, 14, 16, 40 ];
let n = arr.length;
console.log( "Index of a local mimima is " + localMin(arr, n));
|
OutputIndex of a local minima is 2
Time Complexity: O(Log n)
Auxiliary Space: O(log n), As the recursive call is there, hence implicit stack is used.
Related Problem :
Find a peak element
This article is contributed by Roshni Agarwal. 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.