1605.给定行和列的和求可行矩阵
前言
题目来自LeetCode:https://leetcode.cn/problems/find-valid-matrix-given-row-and-column-sums/
题目(难度:中等)
给你两个非负整数数组 rowSum 和 colSum ,其中 rowSum[i] 是二维矩阵中第 i 行元素的和, colSum[j] 是第 j 列元素的和。换言之你不知道矩阵里的每个元素,但是你知道每一行和每一列的和。
请找到大小为 rowSum.length x colSum.length 的任意 非负整数 矩阵,且该矩阵满足 rowSum 和 colSum 的要求。
请你返回任意一个满足题目要求的二维矩阵,题目保证存在 至少一个 可行矩阵。
1 | 示例 1: |
题解
本题难处在于暴力解决的时间复杂度是毁灭性的,最坏情况矩阵是每个元素都有10^8的可能,矩阵最大可达500*500=2.5×10^5,最坏情况可达2.5×10^13。
从优化暴力方法的角度入手,矩阵的每个元素res[i][j]都会小于第i行的和,第j列的和,也就是说,res[i][j] <= min(rowSum[i],colSum[j]),这样搜索范围就减小了,但这远远不够。
由于矩阵是可以取0的,不妨先让res[i][j]取min(rowSum[i],colSum[j]),每取完一个数,就在当前行和与当前列和上减去这个数,就算用尽当行(列)的和,当行(列)剩下的元素还能用0填补。
- 当且只有一行的时候,第一行的和永远会大于等于各列和,所以每次取的数都会是该列的和,数组rolSum即为答案。
- 当行数大于等于2时,矩阵n×m(n >= 2, m >= 1)的第一行按照上述规则取,整行取完后,第一行的行和也就是rowSum[0]会变成0,而colSum整个数组的和会减少rowSum[0],因为不止一行,所以此时colSum这个数组的和还是大于等于0的,又因为每次取的是min(rowSum[i],colSum[j]),所以colSum数组里每个数都还是大于等于0的。即取完一行后仍然和之前的性质没有发生变化。从而使所需矩阵减少成(n - 1) × m,循环往复,最终会使得n = 1,从而求出所需矩阵。
代码
1 | class Solution { |