题目描述
给定两个非负整数数组 rowSum
和 colSum
,其中 rowSum[i]
是二维矩阵中第 i
行元素的和,colSum[j]
是第 j
列元素的和。换言之你不知道矩阵里的每个元素,但是你知道每一行和每一列的和。
请找到大小为 rowSum.length x colSum.length
的任意 非负整数 矩阵,且该矩阵满足 rowSum
和 colSum
的要求。
请你返回任意一个满足题目要求的二维矩阵,题目保证存在 至少一个 可行矩阵。
样例
输入:rowSum = [3,8], colSum = [4,7]
输出:[[3,0],
[1,7]]
解释:
第 0 行:3 + 0 = 0 == rowSum[0]
第 1 行:1 + 7 = 8 == rowSum[1]
第 0 列:3 + 1 = 4 == colSum[0]
第 1 列:0 + 7 = 7 == colSum[1]
行和列的和都满足题目要求,且所有矩阵元素都是非负的。
另一个可行的矩阵为:[[1,2],
[3,5]]
输入:rowSum = [5,7,10], colSum = [8,6,8]
输出:[[0,5,0],
[6,1,0],
[2,0,8]]
输入:rowSum = [14,9], colSum = [6,9,8]
输出:[[0,9,5],
[6,0,3]]
输入:rowSum = [1,0], colSum = [1]
输出:[[1],
[0]]
输入:rowSum = [0], colSum = [0]
输出:[[0]]
限制
1 <= rowSum.length, colSum.length <= 500
0 <= rowSum[i], colSum[i] <= 10^8
sum(rows) == sum(columns)
算法
(贪心) $O(rc)$
- 逐一确定每个位置的值。因为一个位置仅会影响当前行和当前列,所以我们仅需要保证填入的这个数字,不会导致当前行或当前列出现负值就可以。
- 对于位置 $(i, j)$,找到 $rowSum(i)$ 和 $colSum(j)$ 中较小的值 $v$,令 $ans(i, j) = v$,然后 $rowSum(i)$ 和 $colSum(j)$ 分别减去 $v$。
时间复杂度
- 每个位置仅需要常数的时间确定,故总时间复杂度为 $O(rc)$。
空间复杂度
- 仅需要 $O(rc)$ 的额外空间存储答案。
C++ 代码
class Solution {
public:
vector<vector<int>> restoreMatrix(vector<int>& rowSum, vector<int>& colSum) {
const int r = rowSum.size(), c = colSum.size();
vector<vector<int>> ans(r, vector<int>(c));
for (int i = 0; i < r; i++)
for (int j = 0; j < c; j++) {
int v = min(rowSum[i], colSum[j]);
ans[i][j] = v;
rowSum[i] -= v;
colSum[j] -= v;
}
return ans;
}
};
好难