Given a 2D Array/Matrix, the task is to find the Peak element.
An element is a peak element if it is greater than or equal to its four neighbors, left, right, top and bottom.
- A Diagonal adjacent is not considered a neighbour.
- A peak element is not necessarily the maximal element.
- More than one such element can exist.
- There is always a peak element.
- For corner elements, missing neighbors are considered of negative infinite value.
Examples:
Input: [[10 20 15], [21 30 14], [7 16 32]]
Output: 1, 1
Explanation: The value at index {1, 1} is 30, which is a peak element because all its neighbors are smaller or equal to it. Similarly, {2, 2} can also be picked as a peak.
Input: [[10 7], [11 17]]
Output : 1, 1
Naive Approach to Find Peak Element in Matrix
Iterate through all the elements of the Matrix and check if it is greater/equal to all its neighbors. If yes, return the element.
C++
#include <bits/stdc++.h>
using namespace std;
vector< int > findPeakGrid(vector<vector< int > > arr)
{
vector< int > result;
int row = arr.size();
int column = arr[0].size();
for ( int i = 0; i < row; i++) {
for ( int j = 0; j < column; j++) {
if (i > 0)
if (arr[i][j] < arr[i - 1][j])
continue ;
if (j < column - 1)
if (arr[i][j] < arr[i][j + 1])
continue ;
if (i < row - 1)
if (arr[i][j] < arr[i + 1][j])
continue ;
if (j > 0)
if (arr[i][j] < arr[i][j - 1])
continue ;
result.push_back(i);
result.push_back(j);
break ;
}
}
return result;
}
int main()
{
vector<vector< int > > arr = { { 9, 8 }, { 2, 6 } };
vector< int > result = findPeakGrid(arr);
cout << "Peak element found at index: " << result[0]
<< ", " << result[1] << endl;
return 0;
}
|
Java
import java.util.*;
public class Main {
public static List<Integer> findPeakGrid( int [][] arr)
{
List<Integer> result = new ArrayList<>();
int row = arr.length;
int column = arr[ 0 ].length;
for ( int i = 0 ; i < row; i++) {
for ( int j = 0 ; j < column; j++) {
if (i > 0 )
if (arr[i][j] < arr[i - 1 ][j])
continue ;
if (j < column - 1 )
if (arr[i][j] < arr[i][j + 1 ])
continue ;
if (i < row - 1 )
if (arr[i][j] < arr[i + 1 ][j])
continue ;
if (j > 0 )
if (arr[i][j] < arr[i][j - 1 ])
continue ;
result.add(i);
result.add(j);
break ;
}
}
return result;
}
public static void main(String[] args)
{
int [][] arr = { { 9 , 8 }, { 2 , 6 } };
List<Integer> result = findPeakGrid(arr);
System.out.println( "Peak element found at index: "
+ result.get( 0 ) + ", "
+ result.get( 1 ));
}
}
|
Python3
def findPeakGrid(arr):
result = []
row = len (arr)
column = len (arr[ 0 ])
for i in range (row):
for j in range (column):
if i > 0 :
if arr[i][j] < arr[i - 1 ][j]:
continue
if j < column - 1 :
if arr[i][j] < arr[i][j + 1 ]:
continue
if i < row - 1 :
if arr[i][j] < arr[i + 1 ][j]:
continue
if j > 0 :
if arr[i][j] < arr[i][j - 1 ]:
continue
result.append(i)
result.append(j)
break
return result
arr = [[ 9 , 8 ], [ 2 , 6 ]]
result = findPeakGrid(arr)
print ( "Peak element found at index:" , result)
|
C#
using System;
using System.Collections.Generic;
class GFG {
static int [] findPeakGrid( int [][] arr)
{
int [] result = new int [2];
int row = arr.Length;
int column = arr[0].Length;
for ( int i = 0; i < row; i++) {
for ( int j = 0; j < column; j++) {
if (i > 0)
if (arr[i][j] < arr[i - 1][j])
continue ;
if (j < column - 1)
if (arr[i][j] < arr[i][j + 1])
continue ;
if (i < row - 1)
if (arr[i][j] < arr[i + 1][j])
continue ;
if (j > 0)
if (arr[i][j] < arr[i][j - 1])
continue ;
result[0] = i;
result[1] = j;
break ;
}
}
return result;
}
public static void Main()
{
int [][] arr = { new [] { 9, 8 }, new [] { 2, 6 } };
int [] result = findPeakGrid(arr);
Console.WriteLine( "Peak element found at index: "
+ result[0] + "," + result[1]);
}
}
|
Javascript
function findPeakGrid(arr){
let result = [];
let row = arr.length;
let column = arr[0].length;
for (let i = 0; i<row; i++){
for (let j = 0; j<column; j++){
if (i > 0)
if (arr[i][j] < arr[i-1][j]) continue ;
if (j < column-1)
if (arr[i][j] < arr[i][j+1]) continue ;
if (i < row-1)
if (arr[i][j] < arr[i+1][j]) continue ;
if (j > 0)
if (arr[i][j] < arr[i][j-1]) continue ;
result.push(i);
result.push(j);
break ;
}
}
return result;
}
let arr = [[9,8], [2,6]];
let result = findPeakGrid(arr);
console.log( "Peak element found at index: " + result[0] + ", " + result[1]);
|
Output
Peak element found at index: 0, 0
Time Complexity: O(rows * columns)
Auxiliary Space: O(1)
Efficient Approach to Find Peak Element in Matrix
This problem is mainly an extension of Find a peak element in 1D array. We apply similar Binary Search based solution here, as shown below:
- Consider mid column and find maximum element in it.
- Let index of mid column be ‘mid’, value of maximum element in mid column be ‘max’ and maximum element be at ‘mat[max_index][mid]’.
- If max >= A[index][mid-1] & max >= A[index][mid+1], max is a peak, return max.
- If max < mat[max_index][mid-1], recur for left half of matrix.
- If max < mat[max_index][mid+1], recur for right half of matrix.
Below is the implementation of the above algorithm:
C++
#include <bits/stdc++.h>
using namespace std;
#include <bits/stdc++.h>
using namespace std;
vector< int > findPeakGrid(vector<vector< int > >& mat)
{
int stcol = 0,
endcol
= mat[0].size()
- 1;
while (stcol <= endcol) {
int midcol = stcol + (endcol - stcol) / 2,
ansrow = 0;
for ( int r = 0; r < mat.size(); r++) {
ansrow = mat[r][midcol] >= mat[ansrow][midcol]
? r
: ansrow;
}
bool valid_left = midcol - 1 >= stcol
&& mat[ansrow][midcol - 1]
> mat[ansrow][midcol];
bool valid_right = midcol + 1 <= endcol
&& mat[ansrow][midcol + 1]
> mat[ansrow][midcol];
if (!valid_left && !valid_right) {
return { ansrow, midcol };
}
else if (valid_right)
stcol = midcol
+ 1;
else
endcol = midcol
- 1;
}
return { -1, -1 };
}
int main()
{
vector<vector< int > > arr = { { 9, 8 }, { 2, 6 } };
vector< int > result = findPeakGrid(arr);
cout << "Peak element found at index: " << result[0]
<< "," << result[1] << endl;
return 0;
}
|
Java
import java.util.*;
public class GFG {
static int [] findPeakGrid( int [][] mat)
{
int stcol = 0 , endcol = mat[ 0 ].length - 1 ;
while (stcol <= endcol) {
int midcol = stcol + (endcol - stcol) / 2 ,
ansrow = 0 ;
for ( int r = 0 ; r < mat.length; r++) {
ansrow
= mat[r][midcol] >= mat[ansrow][midcol]
? r
: ansrow;
}
boolean valid_left
= midcol - 1 >= stcol
&& mat[ansrow][midcol - 1 ]
> mat[ansrow][midcol];
boolean valid_right
= midcol + 1 <= endcol
&& mat[ansrow][midcol + 1 ]
> mat[ansrow][midcol];
if (!valid_left && !valid_right) {
return new int [] { ansrow, midcol };
}
else if (valid_right)
stcol
= midcol
+ 1 ;
else
endcol
= midcol
- 1 ;
}
return new int [] { - 1 , - 1 };
}
public static void main(String[] args)
{
int [][] arr = { { 9 , 8 }, { 2 , 6 } };
int [] result = findPeakGrid(arr);
System.out.println( "Peak element found at index: "
+ result[ 0 ] + "," + result[ 1 ]);
}
}
|
Python3
def findPeakGrid(mat):
stcol = 0
endcol = len (mat[ 0 ]) - 1
while (stcol < = endcol):
midcol = stcol + int ((endcol - stcol) / 2 )
ansrow = 0
for r in range ( len (mat)):
ansrow = r if mat[r][midcol] > = mat[ansrow][midcol] else ansrow
valid_left = midcol - \
1 > = stcol and mat[ansrow][midcol - 1 ] > mat[ansrow][midcol]
valid_right = midcol + \
1 < = endcol and mat[ansrow][midcol + 1 ] > mat[ansrow][midcol]
if ( not valid_left and not valid_right):
return [ansrow, midcol]
elif (valid_right):
stcol = midcol + 1
else :
endcol = midcol - 1
return [ - 1 , - 1 ]
arr = [[ 9 , 8 ], [ 2 , 6 ]]
result = findPeakGrid(arr)
print ( "Peak element found at index:" , result)
|
C#
using System;
using System.Collections.Generic;
public class GFG {
static int [] findPeakGrid( int [][] mat)
{
int stcol = 0, endcol = mat[0].Length - 1;
while (stcol <= endcol) {
int midcol = stcol + (endcol - stcol) / 2,
ansrow = 0;
for ( int r = 0; r < mat.Length; r++) {
ansrow
= mat[r][midcol] >= mat[ansrow][midcol]
? r
: ansrow;
}
bool valid_left = midcol - 1 >= stcol
&& mat[ansrow][midcol - 1]
> mat[ansrow][midcol];
bool valid_right = midcol + 1 <= endcol
&& mat[ansrow][midcol + 1]
> mat[ansrow][midcol];
if (!valid_left && !valid_right) {
return new int [] { ansrow, midcol };
}
else if (valid_right)
stcol
= midcol
+ 1;
else
endcol
= midcol
- 1;
}
return new int [] { -1, -1 };
}
public static void Main( string [] args)
{
int [][] arr = { new [] { 9, 8 }, new [] { 2, 6 } };
int [] result = findPeakGrid(arr);
Console.WriteLine( "Peak element found at index: "
+ result[0] + "," + result[1]);
}
}
|
Javascript
function findPeakGrid(mat)
{
let stcol = 0, endcol = mat[0].length - 1;
while (stcol <= endcol) {
let midcol = stcol + Math.floor((endcol - stcol) / 2), ansrow = 0;
for (let r = 0; r < mat.length; r++) {
ansrow = mat[r][midcol] >= mat[ansrow][midcol] ? r : ansrow;
}
let valid_left = midcol - 1 >= stcol && mat[ansrow][midcol - 1] > mat[ansrow][midcol];
let valid_right = midcol + 1 <= endcol && mat[ansrow][midcol + 1] > mat[ansrow][midcol];
if (!valid_left && !valid_right) {
return [ ansrow, midcol ];
}
else if (valid_right)
stcol = midcol + 1;
else
endcol = midcol - 1;
}
return [ -1, -1 ];
}
let arr = [[9, 8], [2 ,6]];
let result = findPeakGrid(arr);
console.log( "Peak element found at index: " + result[0] + "," + result[1])
|
Output
Peak element found at index: 0,0
Time Complexity: O(rows * log(columns)). We recur for half the number of columns. In every recursive call, we linearly search for the maximum in the current mid column.
Auxiliary Space: O(columns/2) for Recursion Call Stack
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.
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
09 Jun, 2023
Like Article
Save Article