
题目描述
给你一个 m x n
的整数矩阵 grid
和一个整数 k
。
对于矩阵 grid
中的每个连续的 k x k
子矩阵,计算其中任意两个 不同值 之间的 最小绝对差 。
返回一个大小为 (m - k + 1) x (n - k + 1)
的二维数组 ans
,其中 ans[i][j]
表示以 grid
中坐标 (i, j)
为左上角的子矩阵的最小绝对差。
注意:如果子矩阵中的所有元素都相同,则答案为 0。
子矩阵 (x1, y1, x2, y2)
是一个由选择矩阵中所有满足 x1 <= x <= x2
且 y1 <= y <= y2
的单元格 matrix[x][y]
组成的矩阵。
示例 1:
输入: grid = [[1,8],[3,-2]], k = 2
输出: [[2]]
解释:
- 只有一个可能的
k x k
子矩阵:[[1, 8], [3, -2]]
。
- 子矩阵中的不同值为
[1, 8, 3, -2]
。
- 子矩阵中的最小绝对差为
|1 - 3| = 2
。因此,答案为 [[2]]
。
示例 2:
输入: grid = [[3,-1]], k = 1
输出: [[0,0]]
解释:
- 每个
k x k
子矩阵中只有一个不同的元素。
- 因此,答案为
[[0, 0]]
。
示例 3:
输入: grid = [[1,-2,3],[2,3,5]], k = 2
输出: [[1,2]]
解释:
- 有两个可能的
k × k
子矩阵:
- 以
(0, 0)
为起点的子矩阵:[[1, -2], [2, 3]]
。
- 子矩阵中的不同值为
[1, -2, 2, 3]
。
- 子矩阵中的最小绝对差为
|1 - 2| = 1
。
- 以
(0, 1)
为起点的子矩阵:[[-2, 3], [3, 5]]
。
- 子矩阵中的不同值为
[-2, 3, 5]
。
- 子矩阵中的最小绝对差为
|3 - 5| = 2
。
- 因此,答案为
[[1, 2]]
。
提示:
1 <= m == grid.length <= 30
1 <= n == grid[i].length <= 30
-105 <= grid[i][j] <= 105
1 <= k <= min(m, n)
解法
方法一:枚举
我们可以枚举所有可能的 \(k \times k\) 子矩阵的左上角坐标 \((i, j)\),对于每个子矩阵,我们可以提取出其中的所有元素,放入一个列表 \(\textit{nums}\) 中。然后对 \(\textit{nums}\) 进行排序,接着计算相邻的不同元素之间的绝对差,找到最小的绝对差值。最后将结果存储在一个二维数组中。
时间复杂度 \(O((m - k + 1) \times (n - k + 1) \times k^2 \log(k))\),其中 \(m\) 和 \(n\) 分别是矩阵的行数和列数,而 \(k\) 是子矩阵的大小。空间复杂度 \(O(k^2)\),用于存储每个子矩阵的元素。
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | class Solution:
def minAbsDiff(self, grid: List[List[int]], k: int) -> List[List[int]]:
m, n = len(grid), len(grid[0])
ans = [[0] * (n - k + 1) for _ in range(m - k + 1)]
for i in range(m - k + 1):
for j in range(n - k + 1):
nums = []
for x in range(i, i + k):
for y in range(j, j + k):
nums.append(grid[x][y])
nums.sort()
d = min((abs(a - b) for a, b in pairwise(nums) if a != b), default=0)
ans[i][j] = d
return ans
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 | class Solution {
public int[][] minAbsDiff(int[][] grid, int k) {
int m = grid.length, n = grid[0].length;
int[][] ans = new int[m - k + 1][n - k + 1];
for (int i = 0; i <= m - k; i++) {
for (int j = 0; j <= n - k; j++) {
List<Integer> nums = new ArrayList<>();
for (int x = i; x < i + k; x++) {
for (int y = j; y < j + k; y++) {
nums.add(grid[x][y]);
}
}
Collections.sort(nums);
int d = Integer.MAX_VALUE;
for (int t = 1; t < nums.size(); t++) {
int a = nums.get(t - 1);
int b = nums.get(t);
if (a != b) {
d = Math.min(d, Math.abs(a - b));
}
}
ans[i][j] = (d == Integer.MAX_VALUE) ? 0 : d;
}
}
return ans;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 | class Solution {
public:
vector<vector<int>> minAbsDiff(vector<vector<int>>& grid, int k) {
int m = grid.size(), n = grid[0].size();
vector<vector<int>> ans(m - k + 1, vector<int>(n - k + 1, 0));
for (int i = 0; i <= m - k; ++i) {
for (int j = 0; j <= n - k; ++j) {
vector<int> nums;
for (int x = i; x < i + k; ++x) {
for (int y = j; y < j + k; ++y) {
nums.push_back(grid[x][y]);
}
}
sort(nums.begin(), nums.end());
int d = INT_MAX;
for (int t = 1; t < nums.size(); ++t) {
if (nums[t] != nums[t - 1]) {
d = min(d, abs(nums[t] - nums[t - 1]));
}
}
ans[i][j] = (d == INT_MAX) ? 0 : d;
}
}
return ans;
}
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 | func minAbsDiff(grid [][]int, k int) [][]int {
m, n := len(grid), len(grid[0])
ans := make([][]int, m-k+1)
for i := range ans {
ans[i] = make([]int, n-k+1)
}
for i := 0; i <= m-k; i++ {
for j := 0; j <= n-k; j++ {
var nums []int
for x := i; x < i+k; x++ {
for y := j; y < j+k; y++ {
nums = append(nums, grid[x][y])
}
}
sort.Ints(nums)
d := math.MaxInt
for t := 1; t < len(nums); t++ {
if nums[t] != nums[t-1] {
diff := abs(nums[t] - nums[t-1])
if diff < d {
d = diff
}
}
}
if d != math.MaxInt {
ans[i][j] = d
}
}
}
return ans
}
func abs(x int) int {
if x < 0 {
return -x
}
return x
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 | function minAbsDiff(grid: number[][], k: number): number[][] {
const m = grid.length;
const n = grid[0].length;
const ans: number[][] = Array.from({ length: m - k + 1 }, () => Array(n - k + 1).fill(0));
for (let i = 0; i <= m - k; i++) {
for (let j = 0; j <= n - k; j++) {
const nums: number[] = [];
for (let x = i; x < i + k; x++) {
for (let y = j; y < j + k; y++) {
nums.push(grid[x][y]);
}
}
nums.sort((a, b) => a - b);
let d = Number.MAX_SAFE_INTEGER;
for (let t = 1; t < nums.length; t++) {
if (nums[t] !== nums[t - 1]) {
d = Math.min(d, Math.abs(nums[t] - nums[t - 1]));
}
}
ans[i][j] = d === Number.MAX_SAFE_INTEGER ? 0 : d;
}
}
return ans;
}
|