Leetcode 1072. Flip Columns For Maximum Number of Equal Rows

Problem Explanation

Given a 2D matrix of 0s and 1s, we are to determine the flip operation required such that most of the rows consist of the same elements. A flip operation in this context implies changing a column's elements from 0 to 1 or vice versa.

For example, given the 2D matrix [[0,1],[1,1]] after performing a flip operation on the first column, the row remains [[0,1],[1,1]]. Hence we have a row with equal elements.

Solution Approach

A simple approach could be to iterate through the vector matrix and store the binary representation in an unordered map and then return a count of the most element in the unordered map.

We could also implement this using a hash map to keep track of the rows we have seen. Our goal is to find the number of rows in the matrix that are same or complement of another row. Since matrix has binary numbers, where 2nd row is complement of first row.

Another approach will be to actually flip the column and compare every other row in the matrix with the flipped matrix.

Due to the simplicity of the hash map approach and the fact that this method runs in O(M*N^2) time complexity where M is rows and N is columns, for the solution, we are going to implement the hash map approach.


3class Solution {
5    int maxEqualRowsAfterFlips(vector<vector<int>>& matrix) {
6        int ans = 0;
7        unordered_map<string, int> hash_map;
9        // Iterate through the matrix
10        for (int i = 0; i < matrix.size(); ++i)
11        {
12            // First element switch
13            int switchZor1 = matrix[i][0] == 0 ? 1 : 0;
14            string sHash = "";
16            // hashing bitwise operation on all elements in the current row
17            for (int j = 0; j < matrix[i].size(); ++j)
18            {
19                sHash += matrix[i][j]^switchZor1+'0';
20            }
22            // add to hash map
23            hash_map[sHash]++;
25            // determine maximum 'ans'
26            ans = max(ans, hash_map[sHash]);
27        }
28        return ans;       
29    }

The C++ solution uses a hashmap to track equivalent rows. String representations of rows are created by XOR'ing each element in a row with the first element in the same row. This process essentially provides the string representations of two equivalent rows (one is the original row and the other is the row after the flip). The maximum count of such equivalent rows would be the answer.


We can implement a similar solution in python using python's collections.Counter

3from collections import Counter
5class Solution:
6    def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:
7        matrix = [['1' if element==matrix[i][0] else '0' for element in matrix[i]] for i in range(len(matrix))]
8        return max(Counter(map(''.join, matrix)).values())

The python solution does the same as the c++ solution. It uses a list comprehension to generate the equivalent rows and uses python's inbuilt Counter class to find the maximum frequency of such rows.


The Java solution follows a similar approach as the above given solutions.

3class Solution {
4    public int maxEqualRowsAfterFlips(int[][] matrix) {
5        HashMap<String, Integer> map = new HashMap<>();
6        int maxRowsSame = 0;
7        for(int i = 0; i < matrix.length; i++) {
8            String key = convertTo01String(matrix[i]);
9            map.put(key, map.getOrDefault(key, 0) + 1);
10            maxRowsSame = Math.max(maxRowsSame, map.get(key));
11        }
12        return maxRowsSame;
13    }
15    private String convertTo01String(int[] arr) {
16        StringBuilder strB = new StringBuilder();
17        int flip = arr[0] == 0 ? 1 : -1;
18        for(int num : arr) {
19            strB.append(num * flip);
20        }
21        return strB.toString();
22    }

This Java implementation follows the same logic. However, the string representation here is obtained by flipping each number in the row by multiplying it with flip, which is 1 if the first number in row is 0, else -1. Instead of a single-pass solution like in python, it does this in two separate steps: for each row, it generates the "key" string and then counts the repetitions of each key to finally return the maximum frequency.


Let's now see how we can solve this problem using JavaScript. Unlike Python and Java, JavaScript doesn't have a built-in dictionary or counter. However, we can use a JavaScript object as a hashmap to solve this. Here's how it would look:

4 * @param {number[][]} matrix
5 * @return {number}
6 */
7var maxEqualRowsAfterFlips = function(matrix) {
8    let counts = {};
9    let maxCount = 0;
10    for (let row of matrix) {
11        const r = row.map(val => val == row[0] ? 1 : 0).join("");
12        counts[r] = r in counts ? counts[r] + 1 : 1;
13        maxCount = Math.max(maxCount, counts[r]);
14    }
15    return maxCount;   

This JavaScript implementation makes use of JavaScript objects as a hashmap for counting the occurrence of equivalent rows. It follows a similar approach as the other implementations above: it transforms each row into its equivalent binary form, then counts the occurrence of each binary form in the matrix using an object counts. It then keeps track of the maximum count using the variable maxCount.

Javascript's Array.map is used to perform the transformation on each row: for each element value in the row, if it is the same as the first element, it maps to '1', else '0'. All the values are then joined together as a string. The resulting string representations are then used as keys in the counts object, incrementing the corresponding count for each occurrence.

Next, the maximum count among all keys in the counts object is determined using Math.max, and this is what is finally returned as the result i.e., the number of maximum flip operations needed to make most rows equivalent.

Got a question? Ask the Teaching Assistant anything you don't understand.

Still not clear? Ask in the Forum,  Discord or Submit the part you don't understand to our editors.

TA 👨‍🏫