题目描述#

给定一个下标从 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
}
本站总访问量  ·  访客数
你的IP 获取中…