给你一个二维 boolean 矩阵 grid
。
请你返回使用 grid
中的 3 个元素可以构建的 直角三角形 数目,且满足 3 个元素值 都 为 1 。
注意:
- 如果
grid
中 3 个元素满足:一个元素与另一个元素在 同一行,同时与第三个元素在 同一列 ,那么这 3 个元素称为一个 直角三角形 。这 3 个元素互相之间不需要相邻。
示例 1:
0 | 1 | 0 |
0 | 1 | 1 |
0 | 1 | 0 |
0 | 1 | 0 |
0 | 1 | 1 |
0 | 1 | 0 |
输入:grid = [[0,1,0],[0,1,1],[0,1,0]]
输出:2
解释:
有 2 个直角三角形。
示例 2:
1 | 0 | 0 | 0 |
0 | 1 | 0 | 1 |
1 | 0 | 0 | 0 |
输入:grid = [[1,0,0,0],[0,1,0,1],[1,0,0,0]]
输出:0
解释:
没有直角三角形。
示例 3:
1 | 0 | 1 |
1 | 0 | 0 |
1 | 0 | 0 |
1 | 0 | 1 |
1 | 0 | 0 |
1 | 0 | 0 |
输入:grid = [[1,0,1],[1,0,0],[1,0,0]]
输出:2
解释:
有两个直角三角形。
提示:
1 <= grid.length <= 1000
1 <= grid[i].length <= 1000
0 <= grid[i][j] <= 1
思路:
以每一个 1 元素作为直角顶点能形成的直角三角形的个数,等于(当前行的 1 的数量 - 1) * (当前列的 1 的数量 - 1)。
所以这道题等价于找每一行和每一列 1 出现的次数。
时间复杂度:O(MN)
空间复杂度:O(M + N)
class Solution:
def numberOfRightTriangles(self, grid: List[List[int]]) -> int:
# find out how many 1s are in the same row and same col
if not grid or not grid[0]:
return 0
m, n = len(grid), len(grid[0])
row2one_cnt = defaultdict(int)
col2one_cnt = defaultdict(int)
res = 0
for i, row in enumerate(grid):
row2one_cnt[i] = row.count(1)
for j, col in enumerate(zip(*grid)):
col2one_cnt[j] = col.count(1)
for i in range(m):
for j in range(n):
if grid[i][j] == 1:
res += max(0, (row2one_cnt[i] - 1) * (col2one_cnt[j] - 1))
return res