矩阵的最大非负积
矩阵的最大非负积1
题目描述
题目讲解
矩阵中有正数、负数、0。
乘积遇到负数会翻转符号,因此:
1. 当前格子的 最大乘积 可能来自上方或左方的 最小乘积 × 当前负数。
2. 当前格子的 最小乘积 可能来自上方或左方的 最大乘积 × 当前负数。
故需要维护两个 DP 数组:
1. dpMax[i][j] ---> 到达 (i,j) 的最大乘积.
2. dpMin[i][j] ---> 到达 (i,j) 的最小乘积.
只能从第一行向左走,从第一列向下走.
设当前值为 v = grid[i][j]
从上方来:
candidates from top = {dpMax[i-1][j] * v, dpMin[i-1][j] * v}
从左边来:
candidates from left = {dpMax[i][j-1] * v, dpMin[i][j-1] * v}
具体流程
代码
c++
python
java
class Solution:
def maxProductPath(self, grid):
MOD = 10**9 + 7
m, n = len(grid), len(grid[0])
dpMax = [[0] * n for _ in range(m)]
dpMin = [[0] * n for _ in range(m)]
dpMax[0][0] = dpMin[0][0] = grid[0][0]
# 第一行
for j in range(1, n):
dpMax[0][j] = dpMin[0][j] = dpMax[0][j-1] * grid[0][j]
# 第一列
for i in range(1, m):
dpMax[i][0] = dpMin[i][0] = dpMax[i-1][0] * grid[i][0]
# 其他格子
for i in range(1, m):
for j in range(1, n):
v = grid[i][j]
candidates = [
dpMax[i-1][j] * v,
dpMin[i-1][j] * v,
dpMax[i][j-1] * v,
dpMin[i][j-1] * v
]
dpMax[i][j] = max(candidates)
dpMin[i][j] = min(candidates)
# 取出 dpMax 最后一行, 最后一列 的值,即 到达终点(m-1, n-1)的最大乘积.
result = dpMax[m-1][n-1]
return result % MOD if result >= 0 else -1