一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第14天,点击查看活动详情。
题目说明
给你一个 2 行 n 列的二进制数组:
矩阵是一个二进制矩阵,这意味着矩阵中的每个元素不是 0 就是 1。
第 0 行的元素之和为 upper。
第 1 行的元素之和为 lower。
第 i 列(从 0 开始编号)的元素之和为 colsum[i],colsum 是一个长度为 n 的整数数组。
你需要利用 upper,lower 和 colsum 来重构这个矩阵,并以二维整数数组的形式返回它。
如果有多个不同的答案,那么任意一个都可以通过本题。
如果不存在符合要求的答案,就请返回一个空的二维数组。
示例 1:
输入: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]] 也是正确答案。
计数法
1. colsum中为2的位置,上下两层一定都为1,假设个数为t;
2. colsum中为0的位置,上下两层一定都为0,假设个数为z;
3. colsum中为1的位置数o,`一定等于上下两层的加和upper + lower - 2 * t;`
4. 进行计数,然后逐一分配值即可。
5. 目标返回` [list0,list1] `
1. ` list0、list1元素不是 0 就是1
2. ` upper 为list0 元素1 的个数`
3. lower为list1 元素1 的个数
4. colsum[i] = list0[i]+list1[i]
根据 1 、4 可以得到
(1)colsum[i] =2 那么 list0[0]==list1[0]==1
(2) colsum[i] =0 那么 list0[0]==list1[0]==0
(3) colsum[i] =1 那么 list0[0]+list1[0]==1 即 list1、list0 有一个为0 有一个为1
注意:
- 由于 0 和 2 时情况是固定的,只有 1 的时候才需要讨论,那么我们先确定好 0 和 2,再分配 1
- 由于 0 和 2 分配好了,因此剩余的 1 可以给随意一行进行分配
class Solution {
public List<List<Integer>> reconstructMatrix(int upper, int lower, int[] colsum) {
List<List<Integer>> res = new ArrayList<>() ;
int len = colsum.length ;
int [] arr0 = new int[len] ;
int [] arr1 = new int [len] ;
int n = 0 ;
if(n==lower+upper) {
for(int i=0;i<colsum.length;i++){
if(colsum[i] == 1&&lower>0){
arr1[i] =1 ;
lower-- ;
n-- ;
}else if (colsum[i]==1&& lower==0) {
arr0[i] =1 ;
upper--;
n-- ;
}
}
}else {
return new ArrayList<>() ;
}
List<Integer> list0 = new ArrayList<Integer>() ;
List<Integer> list1 = new ArrayList<Integer>() ;
for (int s : arr0) list0.add(s);
for (int i :arr1) list1.add(i);
res.add(list0);
res.add(list1);
return res;
}
}
注意
其实我感觉这个题目如果是返回int的二维数组更加快些。而且题目贪心也可以做,用也算是一个贪心吧,从列和来看,如果列和为1,优先添加行和多的并且添加的那一行行和减一,如果列和为2,两行都是一,行和各减一。
对于c=1的,先用upper,用完再用lower 此循环不可合并到上面,因为一直先用upper可能导致后面出现c=2时不够用。
最后检查upper和lower的值是否均为0就可以判断是否存在答案。这里就没有放代码了,有兴趣的可以去试试