LC 1605. 给定行和列的和求可行矩阵
从数据量规模上看,这题肯定不是使用回溯方法,此外似乎也没有办法猜测每个元素,比如就没有方法猜测a[0][0]是什么。
这题解法还是通过保持不变量来不断修正剩余行/列上的元素的。假设 rowsum=[R0,R1,R2..Rn], colsum=[C0,C1,…Cm], 我们可以先初始化矩阵为下面这样。
R0 | 0 | 0 | … | 0 |
R1 | 0 | 0 | … | 0 |
R2 | 0 | 0 | … | 0 |
… | 0 | 0 | … | 0 |
Rn | 0 | 0 | … | 0 |
这个矩阵在每行上的和始终是满足rowsum要求的,假设我们就是要不断地修正列,但同时保证行和始终是rowsum.
如果我们分析第一列,假设R0+R1 < C0, 但是R0+R1+R2 > C0,因为要求每个元素都是非负整数,所以情况就会变成这样。
R0 | 0 | 0 | … | 0 |
R1 | 0 | 0 | … | 0 |
C0-R0-R1 | R2-(C0-R0-R1) | 0 | … | 0 |
0 | R3 | 0 | … | 0 |
0 | R4 | 0 | … | 0 |
0 | … | 0 | … | 0 |
0 | Rn | 0 | … | 0 |
这个时候第一列满足条件,并且行和也始终等于rowsum. 依次类推,接着我们调整剩余的列。
class Solution: def restoreMatrix(self, rowSum: List[int], colSum: List[int]) -> List[List[int]]: n = len(rowSum) m = len(colSum) ans = [[0] * m for _ in range(n)] # 保证行之和始终满足,开始调整列 for i in range(n): ans[i][0] = rowSum[i] for j in range(m): acc = 0 for i in range(n): acc += ans[i][j] if acc > colSum[j]: delta = acc - colSum[j] ans[i][j + 1] += delta ans[i][j] -= delta acc -= delta return ans