LeetCode每日一题(2397. Maximum Rows Covered by Columns)

You are given a 0-indexed m x n binary matrix matrix and an integer numSelect, which denotes the number of distinct columns you must select from matrix.

Let us consider s = {c1, c2, …, cnumSelect} as the set of columns selected by you. A row row is covered by s if:

For each cell matrix[row][col] (0 <= col <= n - 1) where matrix[row][col] == 1, col is present in s or,
No cell in row has a value of 1.
You need to choose numSelect columns such that the number of rows that are covered is maximized.

Return the maximum number of rows that can be covered by a set of numSelect columns.

Example 1:

Input: matrix = [[0,0,0],[1,0,1],[0,1,1],[0,0,1]], numSelect = 2
Output: 3

Explanation: One possible way to cover 3 rows is shown in the diagram above.
We choose s = {0, 2}.

  • Row 0 is covered because it has no occurrences of 1.
  • Row 1 is covered because the columns with value 1, i.e. 0 and 2 are present in s.
  • Row 2 is not covered because matrix[2][1] == 1 but 1 is not present in s.
  • Row 3 is covered because matrix[2][2] == 1 and 2 is present in s.
    Thus, we can cover three rows.
    Note that s = {1, 2} will also cover 3 rows, but it can be shown that no more than three rows can be covered.

Example 2:

Input: matrix = [[1],[0]], numSelect = 1
Output: 2

Explanation: Selecting the only column will result in both rows being covered since the entire matrix is selected.
Therefore, we return 2.

Constraints:

  • m == matrix.length
  • n == matrix[i].length
  • 1 <= m, n <= 12
  • matrix[i][j] is either 0 or 1.
  • 1 <= numSelect <= n

想起来容易写起来难, 很容易想到用 bit mask 来解这个问题, 每一行作为一个数, 我们把我们选择的列所对应的位置 0, 如果结果是 0, 那这行就是被覆盖了。 一开始的思路是, 遍历从 0 到 1 << matrix[0].len(), 如果数字中 0 的数量等于 numSelect 我们就检查当前数字 n 与 matrix 中每一行的数字进行 bit and 操作的结果, 如果为 0,则证明可以覆盖此行。但是这里有个前置 0 的问题, 我们没法数前置的 0, 所以我们还需要进行一次曲线救国, 我们从数 0 改为数 1, 只要 1 的数量跟 numSelect 相等即可, 然后我们用一个全为 1 的 mask 与 n 做 xor 操作, 这样我们等于把每一位做翻转,刚才是 1 的位现在全部变为 0 了, 这样就达到了我们开始设想的效果。



impl Solution {
    fn to_int(row: &Vec<i32>) -> i32 {
        row.into_iter().fold(0, |mut s, &v| {
            s *= 2;
            s += v;
            s
        })
    }
    fn check_ones(mut num: i32, ones: i32) -> bool {
        let mut count = 0;
        while num > 0 {
            count += num & 1;
            num = num >> 1;
        }
        count == ones
    }
    pub fn maximum_rows(matrix: Vec<Vec<i32>>, num_select: i32) -> i32 {
        let nums: Vec<i32> = matrix.iter().map(|l| Solution::to_int(l)).collect();
        let mut ans = 0;
        let mask = (1 << matrix[0].len()) - 1;
        for mut n in 0..1 << matrix[0].len() {
            if Solution::check_ones(n, num_select) {
                n ^= mask;
                let mut c = 0;
                for &t in &nums {
                    if n & t == 0 {
                        c += 1;
                    }
                }
                ans = ans.max(c);
            }
        }
        ans
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值