摘要:对于矩阵中每一个连续的 k×k 区域,求该区域内任意两个不同元素之间数值差的最小绝对值。把对每个左上角位于 (i, j) 的 k×k 子块得到的结果按位置放入一个尺寸为 (m - k + 1) × (n - k + 1) 的二维数组 ans,其中 ans[i]
2025-11-16:子矩阵的最小绝对差。用go语言,给定一个大小为 m×n 的整数矩阵 grid 和一个整数 k。
对于矩阵中每一个连续的 k×k 区域,求该区域内任意两个不同元素之间数值差的最小绝对值。把对每个左上角位于 (i, j) 的 k×k 子块得到的结果按位置放入一个尺寸为 (m - k + 1) × (n - k + 1) 的二维数组 ans,其中 ans[i][j] 就是以 (i, j) 为左上角的子块的答案。若某个子块内所有元素都相同,则它的结果记为 0。
注:这里的子矩阵(子块)是指所有满足 x1 ≤ x ≤ x2 且 y1 ≤ y ≤ y2 的单元格所组成的矩形区域。
1
1
-100000
1
输入: grid = [[1,8],[3,-2]], k = 2。
输出: [[2]]。
解释:
只有一个可能的 k x k 子矩阵:[[1, 8], [3, -2]]。
子矩阵中的不同值为 [1, 8, 3, -2]。
子矩阵中的最小绝对差为 |1 - 3| = 2。因此,答案为 [[2]]。
题目来自力扣3567。
1. 初始化阶段:
• 获取输入矩阵 grid 的维度 m(行数)和 n(列数)。
• 创建结果矩阵 ans,其尺寸为 (m - k + 1) × (n - k + 1),用于存储每个 k × k 子矩阵的最小绝对差。初始化时,ans 的所有元素默认值为 0(符合题目要求:若子矩阵元素全相同,结果记为 0)。
• 预分配一个长度为 k² 的临时数组 arr,用于高效存储每个子矩阵的元素,避免重复内存分配。
2. 遍历所有可能的子矩阵:
• 外层循环遍历行起始索引 i(范围:0 到 m - k),内层循环遍历列起始索引 j(范围:0 到 n - k)。每个 (i, j) 对应一个以 (i, j) 为左上角的 k × k 子矩阵。
• 对于每个子矩阵:
• 提取元素:通过嵌套循环遍历该子矩阵的所有行(i 到 i + k - 1)和所有列(j 到 j + k - 1),将元素依次存入临时数组 arr 的切片 a 中(通过 arr[:0] 重用内存,减少开销)。
• 排序元素:对切片 a 中的 k² 个元素进行升序排序(使用 Go 的 slices.Sort)。排序后,最小绝对差必然出现在相邻元素之间。
• 计算最小绝对差:
• 初始化 res 为一个极大值(math.MaxInt)。
• 遍历排序后的 a,计算每对相邻元素的差(a[p] - a[p-1]),并更新 res 为这些差的最小值。
• 如果 res 未被更新(即子矩阵元素全相同或仅有一个元素),则结果保持 0;否则将 res 赋值给 ans[i][j]。
3. 返回结果:
• 遍历完成后,返回结果矩阵 ans,其中每个位置 ans[i][j] 存储了对应子矩阵的最小绝对差。
• 子矩阵总数:存在 (m - k + 1) × (n - k + 1) 个子矩阵,其数量级为 O(mn)。
• 单个子矩阵的处理:
元素提取:需要复制 k² 个元素,时间复杂度为 O(k²)。排序:对 k² 个元素排序,基于比较的排序算法(如 Go 的 slices.Sort)时间复杂度为 O(k² log k²) = O(k² log k)。计算相邻差:遍历排序后的数组,时间复杂度为 O(k²)。• 总时间复杂度:子矩阵数量 × 单个子矩阵处理时间,即 O(mn × k² log k)。
(注:由于 k ≤ min(m, n) 且 m, n ≤ 30,该算法在给定约束下可行。)
• 额外空间(不包括输入和输出):
临时数组 arr:固定大小为 k²,用于存储子矩阵元素,空间复杂度为 O(k²)。排序操作:递归排序算法(如快速排序)的栈空间复杂度为 O(log k²) = O(log k)。• 总额外空间复杂度:O(k²)(主导项)。
(注:结果矩阵 ans 是输出必要空间,通常不计入额外空间复杂度。)
• 优化策略:通过重用临时数组 arr 避免重复内存分配,减少开销。
• 算法依据:利用排序后最小差必出现在相邻元素间的性质,确保正确性。
• 约束处理:当 k = 1 时,子矩阵仅有一个元素,结果直接为 0;当 k > 1 时,正常计算相邻差。
此方法直接但有效,适用于题目中的小规模约束(m, n ≤ 30)。
package mAInimport ( "fmt" "math" "slices")func minAbsDiff(grid int, k int) int { m, n := len(grid), len(grid[0]) ans := make(int, m-k+1) arr := make(int, k*k) for i := range ans { ans[i] = make(int, n-k+1) for j := range ans[i] { a := arr[:0] // 避免反复 make for _, row := range grid[i : i+k] { a = append(a, row[j:j+k]...) } slices.Sort(a) res := math.MaxInt for p := 1; p a[p-1] { res = min(res, a[p]-a[p-1]) } } if res我们相信人工智能为普通人提供了一种“增强工具”,并致力于分享全方位的AI知识。在这里,您可以找到最新的AI科普文章、工具评测、提升效率的秘籍以及行业洞察。
来源:考研冲
