题目描述
给你一个 2
行 n
列的二进制数组:
- 矩阵是一个二进制矩阵,这意味着矩阵中的每个元素不是
0
就是1
。 - 第 0 行的元素之和为
upper
。 - 第 1 行的元素之和为
lower
。 - 第
i
列(从 0 开始编号)的元素之和为colsum[i]
,colsum
是一个长度为n
的整数数组。
你需要利用 upper
,lower
和 colsum
来重构这个矩阵,并以二维整数数组的形式返回它。
如果有多个不同的答案,那么任意一个都可以通过本题。
如果不存在符合要求的答案,就请返回一个空的二维数组。
样例
输入:upper = 2, lower = 1, colsum = [1,1,1]
输出:[[1,1,0],[0,0,1]]
解释:[[1,0,1],[0,1,0]] 和 [[0,1,1],[1,0,0]] 也是正确答案。
输入:upper = 2, lower = 3, colsum = [2,2,1,1]
输出:[]
输入:upper = 5, lower = 5, colsum = [2,1,2,0,1,0,1,2,0,1]
输出:[[1,1,1,0,1,0,0,1,0,0],[1,0,1,0,0,0,1,1,0,1]]
限制
1 <= colsum.length <= 10^5
0 <= upper, lower <= colsum.length
0 <= colsum[i] <= 2
算法
(贪心) $O(n)$
colsum
为 0 或者 2 的列的值可以直接确定,根据情况,更新upper
和lower
,此时upper
和lower
记录当前行还需要多少个 1。如果这时候upper
或lower
小于 0,则直接返回空数组。- 接下来处理
colsum
为 1 的列,如果upper
大于 0,则这一列第一行填 0,第二行填 1,然后upper
减 1。反之亦然。最后处理结束后,如果upper
或lower
仍大于 0,则返回空数组。
时间复杂度
- 每个位置仅遍历两次,故时间复杂度为 $O(n)$。
空间复杂度
- 答案需要额外 $O(n)$ 的空间。
C++ 代码
class Solution {
public:
vector<vector<int>> reconstructMatrix(int upper, int lower, vector<int>& colsum) {
int n = colsum.size();
vector<vector<int>> res(2, vector<int>(n));
for (int i = 0; i < n; i++)
if (colsum[i] == 0) {
res[0][i] = res[1][i] = 0;
} else if (colsum[i] == 2) {
res[0][i] = res[1][i] = 1;
upper--; lower--;
if (upper < 0 || lower < 0)
return {};
}
for (int i = 0; i < n; i++)
if (colsum[i] == 1) {
if (upper > 0) {
res[0][i] = 1; res[1][i] = 0;
upper--;
} else if (lower > 0) {
res[0][i] = 0; res[1][i] = 1;
lower--;
} else {
return {};
}
}
if (upper > 0 || lower > 0)
return {};
return res;
}
};