记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
目录
3/23 1594. 矩阵的最大非负积
动态规划
maxv[i][j]表示从(0,0)到(i,j)的最大非负积
minv[i][j]表示从(0,0)到(i,j)的最小非负积
maxv[i][j] = max(maxv[i-1][j], maxv[i][j-1]) * grid[i][j]
minv[i][j] = min(minv[i-1][j], minv[i][j-1]) * grid[i][j]
最终答案为maxv[m-1][n-1]
python
def maxProductPath(grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
MOD=10**9+7
m,n=len(grid),len(grid[0])
maxv=[[float("inf")]*n for _ in range(m)]
minv=[[float("inf")]*n for _ in range(m)]
maxv[0][0]=grid[0][0]
minv[0][0]=grid[0][0]
for i in range(1,m):
maxv[i][0]=max(maxv[i-1][0]*grid[i][0], minv[i-1][0]*grid[i][0])
minv[i][0]=min(maxv[i-1][0]*grid[i][0], minv[i-1][0]*grid[i][0])
for j in range(1,n):
maxv[0][j]=max(maxv[0][j-1]*grid[0][j], minv[0][j-1]*grid[0][j])
minv[0][j]=min(maxv[0][j-1]*grid[0][j], minv[0][j-1]*grid[0][j])
for i in range(1,m):
for j in range(1,n):
maxv[i][j]=max(maxv[i-1][j]*grid[i][j], maxv[i][j-1]*grid[i][j],minv[i-1][j]*grid[i][j],minv[i][j-1]*grid[i][j])
minv[i][j]=min(minv[i-1][j]*grid[i][j], minv[i][j-1]*grid[i][j],maxv[i-1][j]*grid[i][j],maxv[i][j-1]*grid[i][j])
return -1 if maxv[m-1][n-1]<0 else maxv[m-1][n-1]%MOD
3/24 2906. 构造乘积矩阵
计算前缀积和后缀积
python
def constructProductMatrix(grid):
"""
:type grid: List[List[int]]
:rtype: List[List[int]]
"""
MOD=12345
n,m=len(grid),len(grid[0])
p = [[0]*m for _ in range(n)]
suf=1
for i in range(n-1,-1,-1):
for j in range(m-1,-1,-1):
p[i][j]=suf
suf=suf*grid[i][j]%MOD
pre=1
for i in range(n):
for j in range(m):
p[i][j]=p[i][j]*pre%MOD
pre=pre*grid[i][j]%MOD
return p
3/25 3546. 等和矩阵分割 I
将二维数组转换为一维数组
row,col分别记录行和列的和
依次相加是否等于s/2
python
def canPartitionGrid(grid):
"""
:type grid: List[List[int]]
:rtype: bool
"""
n,m=len(grid),len(grid[0])
row,col = [sum(grid[i]) for i in range(n)], [sum(grid[i][j] for i in range(n)) for j in range(m)]
s=sum(row)
if s%2!=0:
return False
s//=2
cur=0
for i in range(n):
cur+=row[i]
if cur==s:
return True
elif cur>s:
break
cur=0
for j in range(m):
cur+=col[j]
if cur==s:
return True
elif cur>s:
break
return False
3/26 3548. 等和矩阵分割 II
枚举横切和竖切 维护两部分元素和
若两部分和不等 只能在较大的一侧删去一个值为差值的格子
删除后该侧仍需连通:
- 若该侧是至少2x2矩形 删除任意一个格子都连通
- 若该侧是1行或1列 只能删除两端点之一
python
def canPartitionGrid(grid):
"""
:type grid: List[List[int]]
:rtype: bool
"""
m, n = len(grid), len(grid[0])
row_sum = [sum(row) for row in grid]
col_sum = [sum(grid[i][j] for i in range(m)) for j in range(n)]
total = sum(row_sum)
total_cnt = {}
for i in range(m):
for j in range(n):
v = grid[i][j]
total_cnt[v] = total_cnt.get(v, 0) + 1
def add_cnt(cnt, v, d):
nv = cnt.get(v, 0) + d
if nv == 0:
cnt.pop(v, None)
else:
cnt[v] = nv
def can_remove(r1, r2, c1, c2, need, cnt):
h = r2 - r1 + 1
w = c2 - c1 + 1
cells = h * w
if cells <= 1:
return False
if h > 1 and w > 1:
return cnt.get(need, 0) > 0
if h == 1:
return grid[r1][c1] == need or grid[r1][c2] == need
return grid[r1][c1] == need or grid[r2][c1] == need
# 横切: 切在第i行和i+1行之间
top_cnt = {}
bottom_cnt = dict(total_cnt)
top_sum = 0
for i in range(m - 1):
top_sum += row_sum[i]
for j in range(n):
v = grid[i][j]
add_cnt(top_cnt, v, 1)
add_cnt(bottom_cnt, v, -1)
bottom_sum = total - top_sum
if top_sum == bottom_sum:
return True
if top_sum > bottom_sum:
need = top_sum - bottom_sum
if can_remove(0, i, 0, n - 1, need, top_cnt):
return True
else:
need = bottom_sum - top_sum
if can_remove(i + 1, m - 1, 0, n - 1, need, bottom_cnt):
return True
# 竖切: 切在第j列和j+1列之间
left_cnt = {}
right_cnt = dict(total_cnt)
left_sum = 0
for j in range(n - 1):
left_sum += col_sum[j]
for i in range(m):
v = grid[i][j]
add_cnt(left_cnt, v, 1)
add_cnt(right_cnt, v, -1)
right_sum = total - left_sum
if left_sum == right_sum:
return True
if left_sum > right_sum:
need = left_sum - right_sum
if can_remove(0, m - 1, 0, j, need, left_cnt):
return True
else:
need = right_sum - left_sum
if can_remove(0, m - 1, j + 1, n - 1, need, right_cnt):
return True
return False
3/27 2946. 循环移位后的矩阵相似检查
长度为n的数组 往右移动k位 相当于往左移动n-k位
所以奇数行往右移动k位 偶数行往左移动k位相当于往右移动n-k位
python
def areSimilar(self, mat, k):
"""
:type mat: List[List[int]]
:type k: int
:rtype: bool
"""
m,n = len(mat),len(mat[0])
k%=n
for i in range(m):
if i%2==0:
tmp = mat[i][n-k:]+mat[i][:n-k]
if tmp!=mat[i]:
return False
else:
tmp = mat[i][k:]+mat[i][:k]
if tmp!=mat[i]:
return False
return True
3/28
python
3/29
python