Peak in a 2D Array/Matrix (original) (raw)

Last Updated : 21 Mar, 2026

Given a 2D matrix **mat[][], identify any **peak element within the matrix. An element is considered a **peak if it isgreater 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 Yourselfredirect icon

Table of Content

[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 #include using namespace std;

vector findPeakGrid(vector<vector>& 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> 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 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 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]);

`

[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:

#include #include using namespace std;

vector findPeakGrid(vector<vector>& 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> 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 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 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]);

`

**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.