day128 1072. 按列翻转得到最大值等行数(Java)

105 阅读2分钟

题目来源: 1072. 按列翻转得到最大值等行数

题目描述:

  • 描述: 给定 m x n 矩阵 matrix 。 你可以从中选出任意数量的列并翻转其上的 每个 单元格。(即翻转后,单元格的值从 0 变成 1,或者从 1 变为 0 。) 返回 经过一些翻转后,行与行之间所有值都相等的最大行数 
  • 示例:
示例1:
输入:matrix = [[0,1],[1,1]]
输出:1

解释:不进行翻转,有 1 行所有值都相等。

示例2:
输入:matrix = [[0,1],[1,0]]
输出:2

解释:翻转第一列的值之后,这两行都由相等的值组成。

示例2:
输入:matrix = [[0,0,0],[0,0,1],[1,1,0]]
输出:2

解释:翻转前两列的值之后,后两行由相等的值组成。

思路

思路1 题目给定m×n 的矩阵,要求从中选取任意数量的列并翻转其上的每个单元格。单元格仅包含0 或者 1。问最多可以得到多少个由相同元素组成的行。如果某一行全部是 1 或者全部是 0,则表示该行由相同元素组成。

如果翻转固定的某些列,可以使得两个不同的行都变成由相同元素组成的行,那么我们称这两行为本质相同的行。例如 001 和 110 就是本质相同的行。

本质相同的行有什么特点呢?可以发现,本质相同的行只存在两种情况,一种是由 0 开头的行,另一种是由 1 开头的行。在开头的元素确定以后,由于翻转的列已经固定,所以可以推断出后续所有元素是 0 还是 1。

为了方便统计本质相同的行的数量,我们让由1 开头的行全部翻转,翻转后行内元素相同的行即为本质相同的行。之后我们将每一行转成字符串形式存储到哈希表中,遍历哈希表得到最多的本质相同的行的数量即为答案。

具体实现1

class Solution {
    public int maxEqualRowsAfterFlips(int[][] matrix) {
        int m = matrix.length, n = matrix[0].length;
        Map<String, Integer> map = new HashMap<String, Integer>();
        for (int i = 0; i < m; i++) {
            char[] arr = new char[n];
            Arrays.fill(arr, '0');
            for (int j = 0; j < n; j++) {
                // 如果 matrix[i][0] 为 1,则对该行元素进行翻转
                arr[j] = (char) ('0' + (matrix[i][j] ^ matrix[i][0]));
            }
            String s = new String(arr);
            map.put(s, map.getOrDefault(s, 0) + 1);
        }
        int res = 0;
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            res = Math.max(res, entry.getValue());
        }
        return res;
    }
}

复杂度分析1:

  • 时间复杂度:O(mn),其中 m 和 n 分别是矩阵 matrix 的行数和列数。过程中,我们遍历了矩阵中的每个元素各一次,这部分的时间复杂度为O(mn)。哈希表中共有 m 个元素,每个元素长度为 n,所有元素插入和查询的渐进复杂度仍为O(mn)。因此总体时间复杂度为 O(mn)。

  • 空间复杂度:O(m)。哈希表存放了m 个字符串的哈希值,空间复杂度为O(m)。