LeetCode 1253 - Reconstruct a 2-Row Binary Matrix


https://leetcode.com/problems/reconstruct-a-2-row-binary-matrix/
Given the following details of a matrix with n columns and 2 rows :
  • The matrix is a binary matrix, which means each element in the matrix can be 0 or 1.
  • The sum of elements of the 0-th(upper) row is given as upper.
  • The sum of elements of the 1-st(lower) row is given as lower.
  • The sum of elements in the i-th column(0-indexed) is colsum[i], where colsum is given as an integer array with length n.
Your task is to reconstruct the matrix with upperlower and colsum.
Return it as a 2-D integer array.
If there are more than one valid solution, any of them will be accepted.
If no valid solution exists, return an empty 2-D array.

Example 1:
Input: upper = 2, lower = 1, colsum = [1,1,1]
Output: [[1,1,0],[0,0,1]]
Explanation: [[1,0,1],[0,1,0]], and [[0,1,1],[1,0,0]] are also correct answers.
Example 2:
Input: upper = 2, lower = 3, colsum = [2,2,1,1]
Output: []
Example 3:
Input: upper = 5, lower = 5, colsum = [2,1,2,0,1,0,1,2,0,1]
Output: [[1,1,1,0,1,0,0,1,0,0],[1,0,1,0,0,0,1,1,0,1]]

If the column sum is 2 or 0, the choice is obvius.
If it's 1, we set the upper bit if upper is larger than lower, and lower bit otherwise.
public List<List<Integer>> reconstructMatrix(int u, int l, int[] cs) {
    boolean[][] res = new boolean[2][cs.length];
    for (int i = 0; i < cs.length; ++i) {
        res[0][i] = cs[i] == 2 || (cs[i] == 1 && l < u);
        res[1][i] = cs[i] == 2 || (cs[i] == 1 && !res[0][i]);
        u -= res[0][i] ? 1 : 0;
        l -= res[1][i] ? 1 : 0;
    }
    return l == 0 && u == 0 ? new ArrayList(Arrays.asList(res[0], res[1])) : new ArrayList();    
}

https://www.cnblogs.com/onePunchCoder/p/11831345.html
public List<List<Integer>> reconstructMatrix(int upper, int lower, int[] colums) {
        int sum = 0;
        int numof2 = 0;
        for (int colum : colums) {
            sum += colum;
            if (colum == 2) {
                numof2++;
            }
        }
        List<List<Integer>> result = new ArrayList<>();
        if (sum != upper + lower || numof2 > Math.min(upper, lower)) {
            return result;
        }
        List<Integer> upperList = new ArrayList<>();
        List<Integer> lowerList = new ArrayList<>();
        result.add(upperList);
        result.add(lowerList);
        for (int colum : colums) {
            if (colum == 0) {
                upperList.add(0);
                lowerList.add(0);
            } else if (colum == 2) {
                upperList.add(1);
                upper--;
                lowerList.add(1);
                lower--;
            } else {
                if (upper > lower) {
                    upperList.add(1);
                    lowerList.add(0);
                    upper--;
                } else {
                    upperList.add(0);
                    lowerList.add(1);
                    lower--;
                }
            }
        }
        return result;
    }
https://www.codetd.com/en/article/7811117
2, a brief translation:
Construction of a plurality of data rows two columns, and the first row of upper, and the second row of Lower, and to colsum [i] of the i-th column. If such an array does not exist returns NULL

3, code analysis:
  • If the upper + lower does not mean colsum and then return empty.
  • If the number 2 is greater than colsum in upper or lower, return null
  • From left to right, a premise is inserted vertically keep balance. (When colums [i] == 1, if lower> = upper plug, the plug remaining cases)
public List<List<Integer>> reconstructMatrix(int upper, int lower, int[] colums) {
        int sum = 0;
        int numof2 = 0;
        for (int colum : colums) {
            sum += colum;
            if (colum == 2) {
                numof2++;
            }
        }
        List<List<Integer>> result = new ArrayList<>();
        if (sum != upper + lower || numof2 > Math.min(upper, lower)) {
            return result;
        }
        List<Integer> upperList = new ArrayList<>();
        List<Integer> lowerList = new ArrayList<>();
        result.add(upperList);
        result.add(lowerList);
        for (int colum : colums) {
            if (colum == 0) {
                upperList.add(0);
                lowerList.add(0);
            } else if (colum == 2) {
                upperList.add(1);
                upper--;
                lowerList.add(1);
                lower--;
            } else {
                if (upper > lower) {
                    upperList.add(1);
                    lowerList.add(0);
                    upper--;
                } else {
                    upperList.add(0);
                    lowerList.add(1);
                    lower--;
                }
            }
        }
        return result;
    }
https://leetcode.com/problems/reconstruct-a-2-row-binary-matrix/discuss/425170/Detailed-Explanation-using-Greedy-Approach
  • First, intialize both the rows as 0. Now, fill the indices where the vertical column sum is 2 (as they don't have a choice). So, now we only need to make choices for the columns with sum 1. Find out the current sum of the first row. Compare it with the required amount. If the difference becomes negative, it means that there is no solution. Else, greedily fill the required 1s in the top row and the remaining 1s in the bottom row. Finally, check if the sum of the bottom row equals lower
https://leetcode.com/problems/reconstruct-a-2-row-binary-matrix/discuss/425110/O(n)-time-Java-Solution-Easy-to-understand-with-Comments-and-Explaination
We count the number of columns for which we need 1 in both rows(colsum[i] == 2), similarly we count the number of columns for which we need column-sum as 1 and column-sum as 0.
For the columns where we need the column-sum as 2, we definitely know that we need 1 in both the rows, similarly if the column-sum is 0 we know we need to place 0s in both the rows.
For the case where we need column-sum as 1, we need to see if we can have a 1 in row1 or do we have to have a 1 in row2.
For those cases I have done a precomputation and followed a somewhat greedy approach.
The number of columns where we need a 1 in row1 and 0 in row2 is say count1 (as mentioned in code).
We start assigning values to the two rows now by iterating over each value in the colsum array. If we encounter a colsum[i] == 2 or colsum[i] == 0, we assign 1s to both the rows and 0s to both the rows respectively.
For the cases where colsum[i] == 1, we check value of count1 variable which will tell us if we can assign a 1 to row1 or not. If value of count1 > 0, we can assign 1 to row1 and 0 to row2 and we simultaneously decrement count1. Else if count1 == 0, we assign a 0 to row1 and 1 to row2.
    public List<List<Integer>> reconstructMatrix(int upper, int lower, int[] colsum) {
        
        int n = colsum.length;
        int sum0 = 0; // no. of columns with colsum 0
        int sum1 = 0; // no. of columns with colsum 1
        int sum2 = 0; // no. of columns with colsum 2
        
        for(int i = 0; i < n; i++){
            if(colsum[i] == 0) sum0 ++;
            else if(colsum[i] == 1) sum1 ++;
            else sum2 ++;
        }
        
        int count1 = upper - sum2; // no. of columns with 1 in 1st row and 0 in 2nd row
        int count2 = lower - sum2; // no. of columns with 0 in 1st row and 1 in 2nd row
        
        // check if arrangement is possible or not
        if(count1 < 0 || count2 < 0 || count1 + count2 != sum1) return new ArrayList<>();
        
        List<List<Integer>> ans = new ArrayList<>();
        for(int i = 0; i < 2; i++) ans.add(new ArrayList<>());
        
        for(int i = 0; i < n; i++){
            if(colsum[i] == 2){
                ans.get(0).add(1);
                ans.get(1).add(1);
            }
            else if(colsum[i] == 0){
                ans.get(0).add(0);
                ans.get(1).add(0);
            }
            else{
                if(count1 > 0){
                    count1 --;
                    ans.get(0).add(1);
                    ans.get(1).add(0);
                }
                else{
                    ans.get(0).add(0);
                    ans.get(1).add(1);
                }
            }
        }
        
        return ans;
    }
(贪心) O(n)
  1. colsum 为 0 或者 2 的列的值可以直接确定,根据情况,更新 upper 和 lower,此时 upper 和 lower 记录当前行还需要多少个 1。如果这时候 upper 或 lower 小于 0,则直接返回空数组。
  2. 接下来处理 colsum 为 1 的列,如果 upper 大于 0,则这一列第一行填 0,第二行填 1,然后 upper 减 1。反之亦然。最后处理结束后,如果 upper 或 lower 仍大于 0,则返回空数组。

时间复杂度

  • 每个位置仅遍历两次,故时间复杂度为 O(n)

空间复杂度

  • 答案需要额外 O(n) 的空间。
    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;
    }


Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts