3567. Minimum Absolute Difference in Sliding Submatrix
Problem Description
You are given an m x n
integer matrix grid
and an integer k
.
For every contiguous k x k
submatrix of grid
, compute the minimum absolute difference between any two distinct values within that submatrix.
Return a 2D array ans
of size (m - k + 1) x (n - k + 1)
, where ans[i][j]
is the minimum absolute difference in the submatrix whose top-left corner is (i, j)
in grid
.
Note: If all elements in the submatrix have the same value, the answer will be 0.
A submatrix (x1, y1, x2, y2)
is a matrix that is formed by choosing all cells matrix[x][y]
where x1 <= x <= x2
and y1 <= y <= y2
.
Intuition
To solve this problem, focus on every possible k x k
block inside the matrix. For each such block, the minimum absolute difference between two distinct numbers will be smallest when those numbers are closest to each other. Sorting all elements inside the submatrix helps because then the closest numbers will be next to each other in sorted order. We just need to look at all pairs of consecutive numbers in the sorted list, and the smallest difference among them will be our answer for that block. If all elements are identical, the difference is zero, because there are no two distinct values. By repeating this process for every possible top-left corner, we fill up our answer grid.
Solution Approach
The approach is to examine each possible k x k
submatrix in the grid and, for each one, calculate the minimum absolute difference between any two distinct numbers.
-
Enumerate all submatrices: For all valid top-left corners
(i, j)
, where0 <= i <= m - k
and0 <= j <= n - k
, extract thek x k
submatrix starting at that point. -
Collect elements: For each submatrix, gather all elements inside it into a list called
nums
. -
Sort for easy comparison: Sort the
nums
list. When sorted, the smallest absolute difference between two distinct values will be among consecutive elements because those are the closest in value. -
Find minimum difference: Go through the sorted list, look at all adjacent pairs
(a, b)
, and ifa != b
, calculate their absolute difference, updating the minimum found so far. -
Buffer for output: Store each submatrixโs result in the output grid at the position corresponding to the top-left corner of that submatrix.
Pseudocode:
for i in 0 to m-k: for j in 0 to n-k: nums = [] for x in i to i+k-1: for y in j to j+k-1: nums.append(grid[x][y]) sort(nums) minDiff = infinity for t in 1 to len(nums)-1: if nums[t] != nums[t-1]: minDiff = min(minDiff, abs(nums[t] - nums[t-1])) if minDiff == infinity: ans[i][j] = 0 else: ans[i][j] = minDiff
This method ensures every possible submatrix is checked with a clear and direct process, using array sorting to efficiently find the minimum absolute difference between distinct elements.
Ready to land your dream job?
Unlock your dream job with a 2-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's illustrate the solution with a small example.
Suppose
grid = [[1, 3, 2], [4, 3, 1], [5, 6, 2]]
and k = 2
.
Step 1: List all possible 2x2 submatrices and their top-left corners
Since the grid is 3x3 and k=2, valid top-left corners are (0,0)
, (0,1)
, (1,0)
, (1,1)
. The answer grid ans
will be 2 x 2
.
Step 2: Process submatrices
-
Top-left corner (0,0):
- Submatrix:
[[1, 3], [4, 3]]
- Elements:
[1, 3, 4, 3]
- Sort:
[1, 3, 3, 4]
- Differences:
3-1=2
(distinct)3-3=0
(same, skip)4-3=1
(distinct)
- Minimum:
min(2, 1) = 1
ans[0][0] = 1
- Submatrix:
-
Top-left corner (0,1):
- Submatrix:
[[3, 2], [3, 1]]
- Elements:
[3, 2, 3, 1]
- Sort:
[1, 2, 3, 3]
- Differences:
2-1=1
3-2=1
3-3=0
(skip)
- Minimum:
min(1, 1) = 1
ans[0][1] = 1
- Submatrix:
-
Top-left corner (1,0):
- Submatrix:
[[4, 3], [5, 6]]
- Elements:
[4, 3, 5, 6]
- Sort:
[3, 4, 5, 6]
- Differences:
4-3=1
5-4=1
6-5=1
- Minimum:
1
ans[1][0] = 1
- Submatrix:
-
Top-left corner (1,1):
- Submatrix:
[[3, 1], [6, 2]]
- Elements:
[3, 1, 6, 2]
- Sort:
[1, 2, 3, 6]
- Differences:
2-1=1
3-2=1
6-3=3
- Minimum:
1
ans[1][1] = 1
- Submatrix:
Final Output:
ans = [ [1, 1], [1, 1] ]
This matches the expected structure, and demonstrates each step from selecting a submatrix, sorting its contents, and finding the minimum absolute difference between any two distinct values.
Solution Implementation
1from typing import List
2
3class Solution:
4 def minAbsDiff(self, grid: List[List[int]], k: int) -> List[List[int]]:
5 # Get the number of rows and columns
6 m, n = len(grid), len(grid[0])
7 # Initialize the result matrix with appropriate size
8 ans = [[0] * (n - k + 1) for _ in range(m - k + 1)]
9
10 for i in range(m - k + 1):
11 for j in range(n - k + 1):
12 nums = []
13 # Collect all elements from the k x k subgrid
14 for x in range(i, i + k):
15 for y in range(j, j + k):
16 nums.append(grid[x][y])
17 # Sort the numbers to make absolute difference calculation easier
18 nums.sort()
19 # Compute the minimum absolute difference between any two distinct elements
20 min_diff = float('inf')
21 for idx in range(1, len(nums)):
22 if nums[idx] != nums[idx - 1]:
23 diff = abs(nums[idx] - nums[idx - 1])
24 if diff < min_diff:
25 min_diff = diff
26 # If there's no pair with distinct elements, set 0
27 ans[i][j] = 0 if min_diff == float('inf') else min_diff
28
29 return ans
30
1class Solution {
2 public int[][] minAbsDiff(int[][] grid, int k) {
3 int m = grid.length; // Number of rows
4 int n = grid[0].length; // Number of columns
5
6 // Result matrix to hold the minimum absolute difference for each k x k submatrix
7 int[][] ans = new int[m - k + 1][n - k + 1];
8
9 // Traverse all possible top-left corners of k x k submatrices
10 for (int row = 0; row <= m - k; row++) {
11 for (int col = 0; col <= n - k; col++) {
12 List<Integer> elements = new ArrayList<>();
13
14 // Collect all elements in the current k x k submatrix
15 for (int i = row; i < row + k; i++) {
16 for (int j = col; j < col + k; j++) {
17 elements.add(grid[i][j]);
18 }
19 }
20
21 // Sort elements to facilitate comparison of adjacent values
22 Collections.sort(elements);
23
24 int minDiff = Integer.MAX_VALUE;
25 for (int idx = 1; idx < elements.size(); idx++) {
26 int prev = elements.get(idx - 1);
27 int curr = elements.get(idx);
28 // Consider only distinct values
29 if (prev != curr) {
30 minDiff = Math.min(minDiff, Math.abs(curr - prev));
31 }
32 }
33
34 // If all values are the same (minDiff unchanged), store 0, else store minDiff
35 ans[row][col] = (minDiff == Integer.MAX_VALUE) ? 0 : minDiff;
36 }
37 }
38 return ans;
39 }
40}
41
1class Solution {
2public:
3 vector<vector<int>> minAbsDiff(vector<vector<int>>& grid, int k) {
4 int m = grid.size();
5 int n = grid[0].size();
6 // Answer matrix to store minimum absolute difference for each k x k window
7 vector<vector<int>> ans(m - k + 1, vector<int>(n - k + 1, 0));
8
9 // Traverse all possible k x k submatrices
10 for (int i = 0; i <= m - k; ++i) {
11 for (int j = 0; j <= n - k; ++j) {
12 vector<int> elements;
13 // Collect all elements inside the current k x k window
14 for (int x = i; x < i + k; ++x) {
15 for (int y = j; y < j + k; ++y) {
16 elements.push_back(grid[x][y]);
17 }
18 }
19 // Sort window elements to compute minimum difference efficiently
20 sort(elements.begin(), elements.end());
21
22 int minDiff = INT_MAX;
23 // Find the minimum absolute difference between any two different numbers
24 for (int t = 1; t < elements.size(); ++t) {
25 if (elements[t] != elements[t - 1]) {
26 minDiff = min(minDiff, abs(elements[t] - elements[t - 1]));
27 }
28 }
29 // If all elements are the same, set difference to 0
30 ans[i][j] = (minDiff == INT_MAX) ? 0 : minDiff;
31 }
32 }
33 return ans;
34 }
35};
36
1/**
2 * Given a 2D grid and an integer k, for each k x k subgrid, compute the minimal absolute difference
3 * between any two distinct numbers in that subgrid.
4 * @param grid - 2D array of numbers
5 * @param k - Size of the subgrid (k x k)
6 * @returns A 2D array representing minimal absolute difference for each subgrid
7 */
8function minAbsDiff(grid: number[][], k: number): number[][] {
9 const rows: number = grid.length;
10 const cols: number = grid[0].length;
11 // Output array, sized to the number of k x k subgrids that fit in grid
12 const result: number[][] = Array.from({ length: rows - k + 1 }, () => Array(cols - k + 1).fill(0));
13
14 // Iterate over all possible top-left corners of k x k subgrids
15 for (let i = 0; i <= rows - k; i++) {
16 for (let j = 0; j <= cols - k; j++) {
17 const values: number[] = [];
18 // Collect all numbers within this k x k subgrid
19 for (let x = i; x < i + k; x++) {
20 for (let y = j; y < j + k; y++) {
21 values.push(grid[x][y]);
22 }
23 }
24 // Sort numbers to efficiently compute minimal difference
25 values.sort((a, b) => a - b);
26
27 let minDiff: number = Number.MAX_SAFE_INTEGER;
28 // Find minimal absolute difference between any pair of distinct numbers
29 for (let idx = 1; idx < values.length; idx++) {
30 if (values[idx] !== values[idx - 1]) {
31 minDiff = Math.min(minDiff, Math.abs(values[idx] - values[idx - 1]));
32 }
33 }
34 // If all numbers are the same, set minDiff to 0
35 result[i][j] = minDiff === Number.MAX_SAFE_INTEGER ? 0 : minDiff;
36 }
37 }
38 return result;
39}
40
Time and Space Complexity
The time complexity of the code is O((m - k + 1) * (n - k + 1) * k^2 * log(k))
, where m
and n
are the numbers of rows and columns in the grid, and k
is the size of each submatrix. For each possible top-left coordinate (i, j)
of the k x k
submatrix, it collects all k^2
elements, sorts them (O(k^2 log k^2) = O(k^2 log k)
), and then computes the minimum absolute difference between adjacent unique elements.
The space complexity is O(k^2)
for storing the elements of each k x k
submatrix in the temporary nums
list. The output matrix ans
requires O((m - k + 1) * (n - k + 1))
space, but the dominant extra space per submatrix computation is O(k^2)
.
Which technique can we use to find the middle of a linked list?
Recommended Readings
Sorting Summary Comparisons We presented quite a few sorting algorithms and it is essential to know the advantages and disadvantages of each one The basic algorithms are easy to visualize and easy to learn for beginner programmers because of their simplicity As such they will suffice if you don't know any advanced
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Want a Structured Path to Master System Design Too? Donโt Miss This!