题目描述#
给定一个下标从 0 开始、大小为 m × n 的二维整数矩阵 grid,请你构造一个同样大小的矩阵 answer。
对于矩阵 answer 中的每个单元格 (r, c),其值按如下方式计算:
- topLeft[r][c] 表示在矩阵 grid 中,位于单元格 (r, c) 左上方向对角线上的所有元素中,不同值的数量(不包含 (r, c) 自身)。
- bottomRight[r][c] 表示在矩阵 grid 中,位于单元格 (r, c) 右下方向对角线上的所有元素中,不同值的数量(不包含 (r, c) 自身)。
然后:
answer[r][c] = | topLeft[r][c] - bottomRight[r][c] |
矩阵中的一条对角线指从矩阵的最顶行或最左列的某个单元格开始,沿右下方向移动直到矩阵边界结束。
如果单元格 (r1, c1) 和 (r, c) 属于同一条对角线且 r1 < r,则 (r1, c1) 属于 (r, c) 的左上对角线部分。类似地,可以定义右下对角线部分。
请返回矩阵 answer。
知识边界#
Go 语言中没有内置的 Set 类型,通常使用 map 来模拟集合。
最常见的写法是:
set := make(map[int]struct{})其中:
- key 表示集合中的元素
- value 使用
struct{}作为占位符
struct{} 是空结构体类型,不包含任何字段,占用 0 字节内存,因此比使用 bool 更节省空间。
插入元素:
set[val] = struct{}{}判断元素是否存在:
_, ok := set[val]
if ok {
// val 在集合中
}删除元素:
delete(set, val)清空集合:
clear(set)遍历集合:
for k := range set {
fmt.Println(k)
}这种 map[T]struct{} 的写法是 Go 中实现集合的标准方式。
思路#
暴力模拟#
直接模拟题意,分别计算每个位置左上和右下对角线上的不同值数量,最后计算差值。
代码#
func differenceOfDistinctValues(grid [][]int) [][]int {
m := len(grid)
n := len(grid[0])
set := map[int]struct{}{}
ans := make([][]int, m)
for i := range m {
ans[i] = make([]int, n)
for j := range n {
clear(set)
for x, y := i-1, j-1; x >= 0 && y >= 0; x, y = x-1, y-1 {
set[grid[x][y]] = struct{}{}
}
topLeft := len(set)
clear(set)
for x, y := i+1, j+1; x < m && y < n; x, y = x+1, y+1 {
set[grid[x][y]] = struct{}{}
}
bottomRight := len(set)
ans[i][j] = abs(topLeft - bottomRight)
}
}
return ans
}
func abs(i int) int {
if i < 0 {
return -i
}
return i
}