Find the Peak Element in a 2D Array/Matrix

Last Updated : 13 Aug, 2025

Given a 2D matrix mat[][], identify any peak element within the matrix. An element is considered a peak if it is greater than or equal to its four immediate neighbors: top, bottom, left, and right. For corner and edge elements, any missing neighbors are treated as having a value of negative infinity.
A peak element is not necessarily the global maximum, it only needs to satisfy the condition relative to its adjacent elements. Multiple peak elements may exist, and the algorithm may return any one of them.

Examples: 

Input: mat[][] = [[10, 20, 15],
[21, 30, 14],
[7, 16, 32]]
Output: [1, 1]
Explanation: The value at index {1, 1} is 30, which is greater than or equal to all its valid neighbors: Left = 21, Right = 14, Top = 20, Bottom = 16. So, it satisfies the peak condition. Alternatively, {2, 2} with value 32 also qualifies as a peak.

Input: mat[][] = [[17, 7],
[11, 10]]
Output: [0, 0]
Explanation: The value at index {0 0} is 17. Its neighbors are: Right= 7, Bottom = 11. Since 17 is greater than or equal to both (and top and left are out of bounds), it qualifies as a peak element.

Try it on GfG Practice
redirect icon

[Naive Approach] Using Two Loops - O(n × m) Time and O(1) Space

The idea is to iterate through each element in the matrix and check whether it is greater than or equal to all its valid neighbors (top, bottom, left, and right). The first such element found is returned as a peak.

C++
#include <iostream>
#include <vector>
using namespace std;

vector<int> findPeakGrid(vector<vector<int>>& mat) {
    int n = mat.size();
    int m = mat[0].size();

    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            int curr = mat[i][j];
            bool isPeak = true;

            // check top
            if (i > 0 && mat[i - 1][j] > curr)
                isPeak = false;

            // check bottom
            if (i + 1 < n && mat[i + 1][j] > curr)
                isPeak = false;

            // check left
            if (j > 0 && mat[i][j - 1] > curr)
                isPeak = false;

            // check right
            if (j + 1 < m  && mat[i][j + 1] > curr)
                isPeak = false;

            if (isPeak)
                return {i, j};
        }
    }

    return {-1, -1};
}


int main() {
    vector<vector<int>> mat = {
        {10, 20, 15},
        {21, 30, 14},
        {7, 16, 32}
    };

    vector<int> peak = findPeakGrid(mat);
    cout << peak[0] << " " << peak[1] << endl;
    return 0;
}
Java
import java.util.ArrayList;

class GfG {
    public static ArrayList<Integer> findPeakGrid(int[][] mat){
        int n = mat.length;
        int m = mat[0].length;

        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
                int curr = mat[i][j];
                boolean isPeak = true;

                // check top
                if (i > 0 && mat[i - 1][j] > curr)
                    isPeak = false;

                // check bottom
                if (i + 1 < n && mat[i + 1][j] > curr)
                    isPeak = false;

                // check left
                if (j > 0 && mat[i][j - 1] > curr)
                    isPeak = false;

                // check right
                if (j + 1 < m && mat[i][j + 1] > curr)
                    isPeak = false;

                if (isPeak) {
                    ArrayList<Integer> res = new ArrayList<>();
                    res.add(i);
                    res.add(j);
                    return res;
                }
            }
        }

        ArrayList<Integer> res = new ArrayList<>();
        res.add(-1);
        res.add(-1);
        return res;
    }

    public static void main(String[] args) {
        int[][] mat = {
            {10, 20, 15},
            {21, 30, 14},
            {7, 16, 32}
        };

        ArrayList<Integer> peak = findPeakGrid(mat);
        System.out.println(peak.get(0) + " " + peak.get(1));
    }
}
Python
def findPeakGrid(mat):
    n = len(mat)
    m = len(mat[0])

    for i in range(n):
        for j in range(m):
            curr = mat[i][j]
            isPeak = True

            # check top
            if i > 0 and mat[i - 1][j] > curr:
                isPeak = False

            # check bottom
            if i + 1 < n and mat[i + 1][j] > curr:
                isPeak = False

            # check left
            if j > 0 and mat[i][j - 1] > curr:
                isPeak = False

            # check right
            if j + 1 < m and mat[i][j + 1] > curr:
                isPeak = False

            if isPeak:
                return [i, j]

    return [-1, -1]


if __name__ == "__main__":
    mat = [
        [10, 20, 15],
        [21, 30, 14],
        [7, 16, 32]
    ]

    peak = findPeakGrid(mat)
    print(peak[0], peak[1])
C#
using System;
using System.Collections.Generic;

class GfG {
    public static List<int> findPeakGrid(int[][] mat) {
        int n = mat.Length;
        int m = mat[0].Length;

        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
                int curr = mat[i][j];
                bool isPeak = true;

                // check top
                if (i > 0 && mat[i - 1][j] > curr)
                    isPeak = false;

                // check bottom
                if (i + 1 < n && mat[i + 1][j] > curr)
                    isPeak = false;

                // check left
                if (j > 0 && mat[i][j - 1] > curr)
                    isPeak = false;

                // check right
                if (j + 1 < m && mat[i][j + 1] > curr)
                    isPeak = false;

                if (isPeak) {
                    return new List<int> { i, j };
                }
            }
        }

        return new List<int> { -1, -1 };
    }

    public static void Main() {
        int[][] mat = new int[][] {
            new int[] {10, 20, 15},
            new int[] {21, 30, 14},
            new int[] {7, 16, 32}
        };

        List<int> peak = findPeakGrid(mat);
        Console.WriteLine(peak[0] + " " + peak[1]);
    }
}
JavaScript
function findPeakGrid(mat) {
    const n = mat.length;
    const m = mat[0].length;

    for (let i = 0; i < n; ++i) {
        for (let j = 0; j < m; ++j) {
            const curr = mat[i][j];
            let isPeak = true;

            // check top
            if (i > 0 && mat[i - 1][j] > curr)
                isPeak = false;

            // check bottom
            if (i + 1 < n && mat[i + 1][j] > curr)
                isPeak = false;

            // check left
            if (j > 0 && mat[i][j - 1] > curr)
                isPeak = false;

            // check right
            if (j + 1 < m && mat[i][j + 1] > curr)
                isPeak = false;

            if (isPeak)
                return [i, j];
        }
    }

    return [-1, -1];
}

// Driver Code
const mat = [
    [10, 20, 15],
    [21, 30, 14],
    [7, 16, 32]
];

const peak = findPeakGrid(mat);
console.log(peak[0] + " " + peak[1]);

Output
1 1

[Expected Approach] Binary Search on Columns (2D Peak Finding)

This approach uses binary search on the columns of the matrix to efficiently find a peak element. In each iteration, it selects the middle column and identifies the row that contains the maximum element in that column. This element is then compared with its left and right neighbors.
If the current element is greater than or equal to both neighbors, it qualifies as a peak and its position is returned. Otherwise, the search continues in the direction of the larger neighbor (left or right), ensuring movement toward a region that must contain a peak. This process continues until a peak is found.

Step by Step Implementation:

  • Start binary search on columns from low = 0 to high = m - 1, where m is the number of columns.
  • In each iteration, compute the middle column index: mid = (low + high) / 2.
  • Scan all rows in the mid column to find the row index maxRow where the maximum element exists.
  • Retrieve the left neighbor (if exists) and right neighbor (if exists) of mat[maxRow][mid].
  • If a neighbor is missing (edge case), treat it as negative infinity.
  • If the current element is greater than or equal to both its left and right neighbors, return its position {maxRow, mid} as a peak.
  • If the right neighbor is greater, shift search to the right half by setting low = mid + 1.
  • Otherwise, shift search to the left half by setting high = mid - 1.
  • Repeat the process until a peak is found.
C++
#include <iostream>
#include <vector>
using namespace std;


vector<int> findPeakGrid(vector<vector<int>>& mat) {
    int n = mat.size();
    int m = mat[0].size();

    int low = 0, high = m - 1;
    
    int mini = int(-1e9);

    // binary search on columns
    while (low <= high) {
        int mid = (low + high) / 2;

        // find the row with the maximum element in 
        // the current column
        int maxRow = 0;
        for (int i = 1; i < n; ++i) {
            if (mat[i][mid] > mat[maxRow][mid])
                maxRow = i;
        }

        // get the left and right neighbors 
        // treat missing neighbors as -∞
        int left = (mid > 0) ? 
                        mat[maxRow][mid - 1] : mini;
        int right = (mid + 1 < m) ? 
                        mat[maxRow][mid + 1] : mini;

        // check if the current element is greater than or 
        // equal to its neighbors
        if (mat[maxRow][mid] >= left && 
                    mat[maxRow][mid] >= right)
            return {maxRow, mid};

        // if right neighbor is greater, move to right half
        else if (right > mat[maxRow][mid])
            low = mid + 1;

        // else, move to left half
        else
            high = mid - 1;
    }

    return {-1, -1};
}


int main() {
    vector<vector<int>> mat = {
        {10, 20, 15},
        {21, 30, 14},
        {7, 16, 32}
    };

    vector<int> peak = findPeakGrid(mat);
    cout << peak[0] << " " << peak[1] << endl;
    return 0;
}
Java
import java.util.ArrayList;

class GfG {
    public static ArrayList<Integer> findPeakGrid(int[][] mat) {
        int n = mat.length;
        int m = mat[0].length;

        int low = 0, high = m - 1;
    
        int mini = -1000000000;
    
        // binary search on columns
        while (low <= high) {
            int mid = (low + high) / 2;

            // find the row with the maximum element in 
            // the current column
            int maxRow = 0;
            for (int i = 1; i < n; ++i) {
                if (mat[i][mid] > mat[maxRow][mid])
                    maxRow = i;
            }

            // get the left and right neighbors 
            // treat missing neighbors as -∞
            int left = (mid > 0) ? 
                            mat[maxRow][mid - 1] : mini;
            int right = (mid + 1 < m) ? 
                            mat[maxRow][mid + 1] : mini;

            // check if the current element is greater than or 
            // equal to its neighbors
            if (mat[maxRow][mid] >= left && 
                        mat[maxRow][mid] >= right) {
                ArrayList<Integer> res = new ArrayList<>();
                res.add(maxRow);
                res.add(mid);
                return res;
            }

            // if right neighbor is greater, move to right half
            else if (right > mat[maxRow][mid]) {
                low = mid + 1;
            }

            // else, move to left half
            else {
                high = mid - 1;
            }
        }

        ArrayList<Integer> res = new ArrayList<>();
        res.add(-1);
        res.add(-1);
        return res;
    }

    public static void main(String[] args) {
        int[][] mat = {
            {10, 20, 15},
            {21, 30, 14},
            {7, 16, 32}
        };

        ArrayList<Integer> peak = findPeakGrid(mat);
        System.out.println(peak.get(0) + " " + peak.get(1));
    }
}
Python
def findPeakGrid(mat):
    n = len(mat)
    m = len(mat[0])

    low, high = 0, m - 1
    
    mini = int(-1e9)

    # binary search on columns
    while low <= high:
        mid = (low + high) // 2

        # find the row with the maximum element in 
        # the current column
        maxRow = 0
        for i in range(1, n):
            if mat[i][mid] > mat[maxRow][mid]:
                maxRow = i

        # get the left and right neighbors 
        # treat missing neighbors as -∞
        left = mat[maxRow][mid - 1] \
                        if mid > 0 else mini
        right = mat[maxRow][mid + 1] \
                        if mid + 1 < m else mini

        # check if the current element is greater than or 
        # equal to its neighbors
        if mat[maxRow][mid] >= left \
                and mat[maxRow][mid] >= right:
            return [maxRow, mid]

        # if right neighbor is greater, move to right half
        elif right > mat[maxRow][mid]:
            low = mid + 1

        # else, move to left half
        else:
            high = mid - 1

    return [-1, -1]


if __name__ == "__main__":
    mat = [
        [10, 20, 15],
        [21, 30, 14],
        [7, 16, 32]
    ]

    peak = findPeakGrid(mat)
    print(peak[0], peak[1])
C#
using System;
using System.Collections.Generic;

class GfG {
    public static List<int> findPeakGrid(int[][] mat) {
        int n = mat.Length;
        int m = mat[0].Length;

        int low = 0, high = m - 1;
        
        int mini = -1000000000;

        // binary search on columns
        while (low <= high) {
            int mid = (low + high) / 2;

            // find the row with the maximum element in 
            // the current column
            int maxRow = 0;
            for (int i = 1; i < n; ++i) {
                if (mat[i][mid] > mat[maxRow][mid])
                    maxRow = i;
            }

            // get the left and right neighbors 
            // treat missing neighbors as -∞
            int left = (mid > 0) ? 
                        mat[maxRow][mid - 1] : mini;
            int right = (mid + 1 < m) ? 
                        mat[maxRow][mid + 1] : mini;

            // check if the current element is greater than or 
            // equal to its neighbors
            if (mat[maxRow][mid] >= left && 
                        mat[maxRow][mid] >= right)
                return new List<int> { maxRow, mid };

            // if right neighbor is greater, move to right half
            else if (right > mat[maxRow][mid])
                low = mid + 1;

            // else, move to left half
            else
                high = mid - 1;
        }

        return new List<int> { -1, -1 };
    }

    public static void Main() {
        int[][] mat = new int[][] {
            new int[] {10, 20, 15},
            new int[] {21, 30, 14},
            new int[] {7, 16, 32}
        };

        List<int> peak = findPeakGrid(mat);
        Console.WriteLine(peak[0] + " " + peak[1]);
    }
}
JavaScript
function findPeakGrid(mat) {
    const n = mat.length;
    const m = mat[0].length;

    let low = 0, high = m - 1;
    
    let mini = -1000000000;

    // binary search on columns
    while (low <= high) {
        const mid = Math.floor((low + high) / 2);

        // find the row with the maximum element in 
        // the current column
        let maxRow = 0;
        for (let i = 1; i < n; ++i) {
            if (mat[i][mid] > mat[maxRow][mid])
                maxRow = i;
        }

        // get the left and right neighbors 
        // treat missing neighbors as -∞
        const left = (mid > 0) ? 
                    mat[maxRow][mid - 1] : mini;
        const right = (mid + 1 < m) ? 
                    mat[maxRow][mid + 1] : mini;

        // check if the current element is greater than or 
        // equal to its neighbors
        if (mat[maxRow][mid] >= left && 
                    mat[maxRow][mid] >= right)
            return [maxRow, mid];

        // if right neighbor is greater, move to right half
        else if (right > mat[maxRow][mid])
            low = mid + 1;

        // else, move to left half
        else
            high = mid - 1;
    }

    return [-1, -1];
}

// Driver Code
const mat = [
    [10, 20, 15],
    [21, 30, 14],
    [7, 16, 32]
];

const peak = findPeakGrid(mat);
console.log(peak[0] + " " + peak[1]);

Output
1 1

Time Complexity: O(n × log m), for each of the log m iterations (binary search on columns), we scan all n rows to find the maximum in the current column.
Auxiliary Space: O(1), only a constant number of variables are used for tracking indices and comparisons.

Comment