记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
目录
3/16 1878. 矩阵中最大的三个菱形和
枚举菱形中心(i,j)和边长k k=0时为单个格子
菱形边框由4条对角线段组成 每段k个点(不含下一段起点 避免重复)
用set收集所有不同的菱形和 排序取前三大
python
def getBiggestThree(grid):
"""
:type grid: List[List[int]]
:rtype: List[int]
"""
m, n = len(grid), len(grid[0])
sums = set()
for i in range(m):
for j in range(n):
sums.add(grid[i][j])
for k in range(1, min(i, m-1-i, j, n-1-j) + 1):
s = 0
for d in range(k):
s += grid[i-k+d][j+d]
s += grid[i+d][j+k-d]
s += grid[i+k-d][j-d]
s += grid[i-d][j-k+d]
sums.add(s)
return sorted(sums, reverse=True)[:3]
3/17 1727. 重新排列后的最大子矩阵
预处理每列连续1的高度 每行按高度降序排列(模拟列重排)
即matrix[i][j]表示在第i行的第j列往上连续1的个数
排序后第j列的高度h意味着至少有j+1列高度>=h 面积=h*(j+1) 取最大值
python
def largestSubmatrix(matrix):
"""
:type matrix: List[List[int]]
:rtype: int
"""
m, n = len(matrix), len(matrix[0])
for i in range(1, m):
for j in range(n):
if matrix[i][j]:
matrix[i][j] += matrix[i-1][j]
ans = 0
for i in range(m):
row = sorted(matrix[i], reverse=True)
for j in range(n):
ans = max(ans, row[j] * (j + 1))
return ans
3/18 3070. 元素和小于等于 k 的子矩阵的数目
固定左上角开始 每个元素>0 右下角越往右下矩阵和越大
根据前缀和计算 mx[i][j] 代表以(i,j)为右下角的矩阵和
mx[i][j]=mx[i-1][j]+mx[i][j-1]-mx[i-1][j-1]+grid[i][j]
实际mx多一行一列方便计算
如果当前mx[i][j]>k 这一行后续都不满足条件
可以提前终止
python
def countSubmatrices(grid, k):
"""
:type grid: List[List[int]]
:type k: int
:rtype: int
"""
n,m=len(grid),len(grid[0])
mx=[[0]*(m+1) for _ in range(n+1)]
ans=0
for i in range(1,n+1):
for j in range(1,m+1):
mx[i][j]=mx[i-1][j]+mx[i][j-1]-mx[i-1][j-1]+grid[i-1][j-1]
if mx[i][j]<=k:
ans+=1
else:
break
return ans
3/19 3212. 统计 X 和 Y 频数相等的子矩阵数量
将X看作为1 将Y看作为-1 统计前缀和 如果前缀和为0 则说明X和Y频数相等
使用tag[i][j]记录以(i,j)为右下角的子矩阵中是否包含X
python
def numberOfSubmatrices(self, grid):
"""
:type grid: List[List[str]]
:rtype: int
"""
m,n=len(grid),len(grid[0])
mx=[[0]*(n+1) for _ in range(m+1)]
tag=[[False]*(n+1) for _ in range(m+1)]
for i in range(1,m+1):
for j in range(1,n+1):
mx[i][j]=mx[i-1][j]+mx[i][j-1]-mx[i-1][j-1]+int(grid[i-1][j-1]=='X')-int(grid[i-1][j-1]=='Y')
tag[i][j]=tag[i-1][j] or tag[i][j-1] or grid[i-1][j-1]=='X'
ans=0
for i in range(1,m+1):
for j in range(1,n+1):
if mx[i][j]==0 and tag[i][j]:
ans+=1
return ans
3/20 3567. 子矩阵的最小绝对差
遍历所有子矩阵 将所有元素排序后 计算相邻元素的差值绝对值最小值
python
def minAbsDiff(grid, k):
"""
:type grid: List[List[int]]
:type k: int
:rtype: List[List[int]]
"""
m, n = len(grid), len(grid[0])
ans = []
for i in range(m - k + 1):
row = []
for j in range(n - k + 1):
vals = sorted(set(grid[r][c] for r in range(i, i+k) for c in range(j, j+k)))
diff = 0 if len(vals) == 1 else min(vals[t+1]-vals[t] for t in range(len(vals)-1))
row.append(diff)
ans.append(row)
return ans
3/21
python
3/22
python