返回介绍

solution / 2100-2199 / 2128.Remove All Ones With Row and Column Flips / README

发布于 2024-06-17 01:03:09 字数 4434 浏览 0 评论 0 收藏 0

2128. 通过翻转行或列来去除所有的 1

English Version

题目描述

给你一个大小为 m x n 的二进制矩阵 grid

每次操作,你可以选择 任意 一行 或者 一列,然后将其中的所有值翻转(0 变成 11变成 0)。

如果经过 任意次 操作,你能将矩阵中所有的 1 去除,那么返回 true;否则返回 false

 

示例 1:

输入: grid = [[0,1,0],[1,0,1],[0,1,0]]
输出: true
解释: 一种去除所有 1 的可行方法是:
- 翻转矩阵的中间的行
- 翻转矩阵的中间的列

示例 2:

输入: grid = [[1,1,0],[0,0,0],[0,0,0]]
输出: false
解释: 不可能去除矩阵中所有的 1。

示例 3:

输入: grid = [[0]]
输出: true
解释: 矩阵中不存在 1,已经符合要求。

 

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 300
  • grid[i][j] 是 0 或者 1.

解法

方法一:哈希表

我们观察发现,如果矩阵中的两行满足以下条件之一,则它们可以通过翻转某些列的方式得到相等的行:

  1. 两行的对应位置元素相等,即如果其中一行元素为 $1,0,0,1$,则另一行元素也为 $1,0,0,1$;
  2. 两行的对应位置元素相反,即如果其中一行元素为 $1,0,0,1$,则另一行元素为 $0,1,1,0$。

我们称满足以上条件之一的两行元素为“等价行”,那么题目所求的答案即为矩阵中最多包含等价行的行数。

因此,我们可以遍历矩阵的每一行,将每一行转换成第一个元素为 $0$ 的“等价行”。具体做法如下:

  • 如果当前行的第一个元素为 $0$,那么当前行的元素保持不变;
  • 如果当前行的第一个元素为 $1$,那么我们将当前行的每个元素进行翻转,即 $0$ 变成 $1$, $1$ 变成 $0$。也就是说,我们将以 $1$ 开头的行翻转成以 $0$ 开头的“等价行”。

这样一来,我们只需要用一个哈希表来统计转换后的每一行,如果最后哈希表只有一个元素,那么说明我们可以通过翻转行或列,将矩阵中所有的 $1$ 去除。

时间复杂度 $O(m \times n)$,空间复杂度 $O(m)$。其中 $m$ 和 $n$ 分别是矩阵的行数和列数。

相似题目:

class Solution:
  def removeOnes(self, grid: List[List[int]]) -> bool:
    s = set()
    for row in grid:
      t = tuple(row) if row[0] == grid[0][0] else tuple(x ^ 1 for x in row)
      s.add(t)
    return len(s) == 1
class Solution {
  public boolean removeOnes(int[][] grid) {
    Set<String> s = new HashSet<>();
    int n = grid[0].length;
    for (var row : grid) {
      var cs = new char[n];
      for (int i = 0; i < n; ++i) {
        cs[i] = (char) (row[0] ^ row[i]);
      }
      s.add(String.valueOf(cs));
    }
    return s.size() == 1;
  }
}
class Solution {
public:
  bool removeOnes(vector<vector<int>>& grid) {
    unordered_set<string> s;
    for (auto& row : grid) {
      string t;
      for (int x : row) {
        t.push_back('0' + (row[0] == 0 ? x : x ^ 1));
      }
      s.insert(t);
    }
    return s.size() == 1;
  }
};
func removeOnes(grid [][]int) bool {
  s := map[string]bool{}
  for _, row := range grid {
    t := []byte{}
    for _, x := range row {
      if row[0] == 1 {
        x ^= 1
      }
      t = append(t, byte(x)+'0')
    }
    s[string(t)] = true
  }
  return len(s) == 1
}
function removeOnes(grid: number[][]): boolean {
  const s = new Set<string>();
  for (const row of grid) {
    if (row[0] === 1) {
      for (let i = 0; i < row.length; i++) {
        row[i] ^= 1;
      }
    }
    const t = row.join('');
    s.add(t);
  }
  return s.size === 1;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文