Max Diff with Below and Right in Grid

Last Updated : 26 Jul, 2026

Given a square matrix mat[][] of size n * n, select two elements such that the second element lies strictly below and strictly to the right of the first element.
Return the maximum possible difference between these two elements.
In other words, for any two elements mat[a][b] and mat[c][d], find the maximum value of mat[c][d] - mat[a][b] such that c > a and d > b.

Examples:

Input: mat = [[1, 2, -1, -4, -20], [-8, -3, 4, 2, 1], [3, 8, 6, 1, 3], [-4, -1, 1, 7, -6], [0, -4, 10, -5, 1]]
Output: 18
Explanation: Choose -8 at position (1, 0) and 10 at position (4, 2). Since the second element is strictly below and strictly to the right of the first element, 10 - (-8) = 18, which is the maximum possible difference.

Input: mat = [[5, 4], [3, 2]]
Output: -3
Explanation: The only valid pair is 5 and 2. 2 - 5 = -3. Hence, the maximum possible difference is -3.

Try It Yourself
redirect icon

[Naive Approach] Try Every Pair - O(n^4) Time and O(1) Space

Every possible pair of positions (a, b) and (c, d) with c > a and d > b can be checked directly, computing mat[c][d] - mat[a][b] for each and tracking the maximum found. Since this involves iterating over every possible first position and then every possible second position that lies strictly below and to the right, the total work grows with the fourth power of the matrix dimension, which becomes very slow for large matrices.

Illustration:

  • Take mat = [[5, 4], [3, 2]].
  • The only position that has anything strictly below and to the right of it is (0, 0), with value 5.
  • The only valid second position is (1, 1), with value 2.
  • Computing 2 - 5 gives -3, which is checked against all other pairs, but since no other valid pair exists in this 2x2 matrix, -3 is the final answer.
C++
#include <bits/stdc++.h>
using namespace std;

int findMaxValue(vector<vector<int>>& mat) {
    int n = mat.size();
    int res = INT_MIN;

    // try every valid pair of positions directly
    for (int a = 0; a < n; a++) {
        for (int b = 0; b < n; b++) {
            for (int c = a + 1; c < n; c++) {
                for (int d = b + 1; d < n; d++) {
                    res = max(res, mat[c][d] - mat[a][b]);
                }
            }
        }
    }

    return res;
}

int main() {
    vector<vector<int>> mat = {{5, 4}, {3, 2}};

    cout << findMaxValue(mat) << endl;

    return 0;
}
Java
class GfG {
    static int findMaxValue(int[][] mat) {
        int n = mat.length;
        int res = Integer.MIN_VALUE;

        // try every valid pair of positions directly
        for (int a = 0; a < n; a++) {
            for (int b = 0; b < n; b++) {
                for (int c = a + 1; c < n; c++) {
                    for (int d = b + 1; d < n; d++) {
                        res = Math.max(res, mat[c][d] - mat[a][b]);
                    }
                }
            }
        }

        return res;
    }

    public static void main(String[] args) {
        int[][] mat = {{5, 4}, {3, 2}};

        System.out.println(findMaxValue(mat));
    }
}
Python
def findMaxValue(mat):
    n = len(mat)
    res = float('-inf')

    # try every valid pair of positions directly
    for a in range(n):
        for b in range(n):
            for c in range(a + 1, n):
                for d in range(b + 1, n):
                    res = max(res, mat[c][d] - mat[a][b])

    return res

mat = [[5, 4], [3, 2]]
print(findMaxValue(mat))
C#
using System;

class GfG {
    static int findMaxValue(int[][] mat) {
        int n = mat.Length;
        int res = int.MinValue;

        // try every valid pair of positions directly
        for (int a = 0; a < n; a++) {
            for (int b = 0; b < n; b++) {
                for (int c = a + 1; c < n; c++) {
                    for (int d = b + 1; d < n; d++) {
                        res = Math.Max(res, mat[c][d] - mat[a][b]);
                    }
                }
            }
        }

        return res;
    }

    static void Main() {
        int[][] mat = { new int[]{5, 4}, new int[]{3, 2} };

        Console.WriteLine(findMaxValue(mat));
    }
}
JavaScript
function findMaxValue(mat) {
    const n = mat.length;
    let res = -Infinity;

    // try every valid pair of positions directly
    for (let a = 0; a < n; a++) {
        for (let b = 0; b < n; b++) {
            for (let c = a + 1; c < n; c++) {
                for (let d = b + 1; d < n; d++) {
                    res = Math.max(res, mat[c][d] - mat[a][b]);
                }
            }
        }
    }

    return res;
}

// Driver Code
const mat = [[5, 4], [3, 2]];
console.log(findMaxValue(mat));

Output
-3

[Expected Approach] Suffix Maximum (Space Optimized) - O(n^2) Time and O(n) Space

For each position (a,b), the optimal second element is the maximum value strictly below and to the right. Compute these using suffix maxima from the bottom-right to the top-left, ensuring the required maximum is already available when processing a cell. Since each row depends only on the row below, only the current and next suffix-maximum rows need to be stored, reducing memory usage.

Illustration:

  • Take mat = [[1,2,-1,-4,-20],[-8,-3,4,2,1],[3,8,6,1,3],[-4,-1,1,7,-6],[0,-4,10,-5,1]].
  • Processing starts from the last row (row 4): its suffix maxima from right to left are [10, 10, 10, -5, 1].
  • Moving to row 3, at position (3, 0) with value -4, the best value strictly below-right (from the next row's suffix maxima) is checked to update the running answer, and the suffix maximum for the current row is built using both the current row and the row below.
  • This process continues upward, and at row 1, position (1, 0) with value -8 is reached; the suffix maximum for the submatrix below-right of it (which includes position (4, 2) with value 10) gives 10 - (-8) = 18.
  • Continuing through all remaining positions confirms no pair produces a larger difference, so 18 is the final answer.
C++
#include <bits/stdc++.h>
using namespace std;

int findMaxValue(vector<vector<int>>& mat) {
    int n = mat.size();

    // only the next row's suffix maxima are 
    // needed, not the full matrix
    vector<int> nextRow(n);
    nextRow[n - 1] = mat[n - 1][n - 1];

    // fill the last row's suffix maxima from right to left
    for (int j = n - 2; j >= 0; j--)
        nextRow[j] = max(mat[n - 1][j], nextRow[j + 1]);

    int res = INT_MIN;

    // process each row from bottom to top, 
    // keeping only the current and next row
    for (int i = n - 2; i >= 0; i--) {
        vector<int> curRow(n);
        curRow[n - 1] = max(mat[i][n - 1], nextRow[n - 1]);

        for (int j = n - 2; j >= 0; j--) {
            
            // update the answer using the best valid 
            // element strictly below-right
            res = max(res, nextRow[j + 1] - mat[i][j]);

            // store the suffix maximum for this cell
            curRow[j] = max({mat[i][j], nextRow[j], curRow[j + 1], nextRow[j + 1]});
        }

        nextRow = curRow;
    }

    return res;
}

int main() {
    vector<vector<int>> mat = {
        {1, 2, -1, -4, -20},
        {-8, -3, 4, 2, 1},
        {3, 8, 6, 1, 3},
        {-4, -1, 1, 7, -6},
        {0, -4, 10, -5, 1}
    };

    cout << findMaxValue(mat) << endl;

    return 0;
}
Java
class GfG {
    static int findMaxValue(int[][] mat) {
        int n = mat.length;

        // only the next row's suffix maxima are 
        // needed, not the full matrix
        int[] nextRow = new int[n];
        nextRow[n - 1] = mat[n - 1][n - 1];

        // fill the last row's suffix maxima 
        // from right to left
        for (int j = n - 2; j >= 0; j--)
            nextRow[j] = Math.max(mat[n - 1][j], nextRow[j + 1]);

        int res = Integer.MIN_VALUE;

        // process each row from bottom to top,
        // keeping only the current and next row
        for (int i = n - 2; i >= 0; i--) {
            int[] curRow = new int[n];
            curRow[n - 1] = Math.max(mat[i][n - 1], nextRow[n - 1]);

            for (int j = n - 2; j >= 0; j--) {
                
                // update the answer using the best valid 
                // ement strictly below-right
                res = Math.max(res, nextRow[j + 1] - mat[i][j]);

                // store the suffix maximum for this cell
                curRow[j] = Math.max(mat[i][j], Math.max(nextRow[j], Math.max(curRow[j + 1], nextRow[j + 1])));
            }

            nextRow = curRow;
        }

        return res;
    }

    public static void main(String[] args) {
        int[][] mat = {
            {1, 2, -1, -4, -20},
            {-8, -3, 4, 2, 1},
            {3, 8, 6, 1, 3},
            {-4, -1, 1, 7, -6},
            {0, -4, 10, -5, 1}
        };

        System.out.println(findMaxValue(mat));
    }
}
Python
def findMaxValue(mat):
    n = len(mat)

    # only the next row's suffix maxima are needed, 
    # not the full matrix
    nextRow = [0] * n
    nextRow[n - 1] = mat[n - 1][n - 1]

    # fill the last row's suffix maxima from right to left
    for j in range(n - 2, -1, -1):
        nextRow[j] = max(mat[n - 1][j], nextRow[j + 1])

    res = float('-inf')

    # process each row from bottom to top,
    # keeping only the current and next row
    for i in range(n - 2, -1, -1):
        curRow = [0] * n
        curRow[n - 1] = max(mat[i][n - 1], nextRow[n - 1])

        for j in range(n - 2, -1, -1):
            
            # update the answer using the best valid 
            # element strictly below-right
            res = max(res, nextRow[j + 1] - mat[i][j])

            # store the suffix maximum for this cell
            curRow[j] = max(mat[i][j], nextRow[j], curRow[j + 1], nextRow[j + 1])

        nextRow = curRow

    return res

mat = [
    [1, 2, -1, -4, -20],
    [-8, -3, 4, 2, 1],
    [3, 8, 6, 1, 3],
    [-4, -1, 1, 7, -6],
    [0, -4, 10, -5, 1]
]
print(findMaxValue(mat))
C#
using System;

class GfG {
    static int findMaxValue(int[][] mat) {
        int n = mat.Length;

        // only the next row's suffix maxima are needed, 
        // not the full matrix
        int[] nextRow = new int[n];
        nextRow[n - 1] = mat[n - 1][n - 1];

        // fill the last row's suffix maxima from right to left
        for (int j = n - 2; j >= 0; j--)
            nextRow[j] = Math.Max(mat[n - 1][j], nextRow[j + 1]);

        int res = int.MinValue;

        // process each row from bottom to top, 
        // keeping only the current and next row
        for (int i = n - 2; i >= 0; i--) {
            int[] curRow = new int[n];
            curRow[n - 1] = Math.Max(mat[i][n - 1], nextRow[n - 1]);

            for (int j = n - 2; j >= 0; j--) {
                
                // update the answer using the best valid element strictly below-right
                res = Math.Max(res, nextRow[j + 1] - mat[i][j]);

                // store the suffix maximum for this cell
                curRow[j] = Math.Max(mat[i][j], Math.Max(nextRow[j], Math.Max(curRow[j + 1], nextRow[j + 1])));
            }

            nextRow = curRow;
        }

        return res;
    }

    static void Main() {
        int[][] mat = {
            new int[]{1, 2, -1, -4, -20},
            new int[]{-8, -3, 4, 2, 1},
            new int[]{3, 8, 6, 1, 3},
            new int[]{-4, -1, 1, 7, -6},
            new int[]{0, -4, 10, -5, 1}
        };

        Console.WriteLine(findMaxValue(mat));
    }
}
JavaScript
// Driver Code
function findMaxValue(mat) {
    const n = mat.length;

    // only the next row's suffix maxima are
    // needed, not the full matrix
    let nextRow = new Array(n).fill(0);
    nextRow[n - 1] = mat[n - 1][n - 1];

    // fill the last row's suffix maxima from right to left
    for (let j = n - 2; j >= 0; j--)
        nextRow[j] = Math.max(mat[n - 1][j], nextRow[j + 1]);

    let res = -Infinity;

    // process each row from bottom to top, 
    // keeping only the current and next row
    for (let i = n - 2; i >= 0; i--) {
        const curRow = new Array(n).fill(0);
        curRow[n - 1] = Math.max(mat[i][n - 1], nextRow[n - 1]);

        for (let j = n - 2; j >= 0; j--) {
            
            // update the answer using the best 
            // valid element strictly below-right
            res = Math.max(res, nextRow[j + 1] - mat[i][j]);

            // store the suffix maximum for this cell
            curRow[j] = Math.max(mat[i][j], nextRow[j], curRow[j + 1], nextRow[j + 1]);
        }

        nextRow = curRow;
    }

    return res;
}

const mat = [
    [1, 2, -1, -4, -20],
    [-8, -3, 4, 2, 1],
    [3, 8, 6, 1, 3],
    [-4, -1, 1, 7, -6],
    [0, -4, 10, -5, 1]
];
console.log(findMaxValue(mat));

Output
18
Comment