LeetCode破解之重构2行二进制矩阵

139 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 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就可以判断是否存在答案。这里就没有放代码了,有兴趣的可以去试试