2732.力扣每日一题6/25 Java

  • 博客主页:音符犹如代码
  • 系列专栏:算法练习
  • 关注博主,后期持续更新系列文章
  • 如果有错误感谢请大家批评指出,及时修改
  • 感谢大家点赞👍收藏⭐评论✍ 

目录

思路

解题方法

复杂度

Code


方法一:哈希表+位运算

思路

  • 首先遍历矩阵的每一行,将每行转化为一个整数表示(通过位运算),并记录每个整数对应的行索引。
  • 然后检查是否存在某一行全为 0 的情况,若有则直接返回该行索引。
  • 接着遍历已记录的整数对,看是否存在两个整数按位与为 0 的情况,如果找到这样的一对,就返回对应的两行索引。

解题方法

通过位运算处理每行数据,利用哈希表记录信息,然后通过双重循环查找满足条件的行对。

时间复杂度

主要时间消耗在两层循环上,循环次数为已记录整数个数的平方,即O(n²)(n其中为不同整数的个数,通常小于矩阵的行数)。

空间复杂度

使用了一个哈希表来存储整数和行索引,空间复杂度为O(n)。

Code

class Solution {
    public List<Integer> goodSubsetofBinaryMatrix(int[][] grid) {
        int m = grid.length;
        int n = grid[0].length;
        Map<Integer, Integer> int2idx = new HashMap<>();
        for (int i = 0; i < m; i++) {
            int x = 0;
            for (int j = 0; j < n; j++) {
                x |= (grid[i][j] << j);
            }
            if (x == 0) {
                return List.of(i);
            }
            int2idx.put(x, i);
        }

        for (int x : int2idx.keySet()) {
            for (int y : int2idx.keySet()) {
                if ((x & y) == 0) {
                    int i = int2idx.get(x);
                    int j = int2idx.get(y);
                    if (i > j) {
                        return List.of(j, i);
                    } else {
                        return List.of(i, j);
                    }
                }
            }
        }
        return List.of();
    }
}

方法二:二进制

思路

看到这一题,首先可以注意到,每一行的二进制表示与每一列的二进制表示进行按位与操作,得到的结果就是该行中1的个数。因此,我们可以通过计算每一行的二进制表示与相应的列的二进制表示进行按位与操作,然后将结果相加,得到的结果就是该行中1的个数。

解题方法

1.首先,我们需要遍历整个矩阵,计算每一列的和。这可以通过位运算来实现,将每一行的二进制表示与相应的列的二进制表示进行按位与操作,然后将结果相加。


2.接下来,我们需要检查每一列是否可以找到一个子集,其大小不超过该列和的一半。这可以通过位运算来实现,将每一列的二进制表示与相应的列的二进制表示进行按位与操作,然后将结果与该列的二进制表示进行比较。如果结果等于该列的二进制表示,那么说明可以找到一个子集,其大小不超过该列和的一半。


3.最后,我们需要检查每一对键是否相与为0。这可以通过位运算来实现,将每一对键的按位与操作结果与0进行比较。如果结果等于0,那么说明可以找到一个好子集,返回这两个行号。

时间复杂度

O(n2)

空间复杂度

O(n2)

Code

public class Solution{
    public List<Integer> goodSubsetofBinaryMatrix(int[][] grid) {
        Map<Integer, Integer> maskToIdx = new HashMap<>();
        for (int i = 0; i < grid.length; i++) {
            int mask = 0;
            for (int j = 0; j < grid[i].length; j++) {
                mask |= grid[i][j] << j;
            }
            if (mask == 0) {
                return List.of(i);
            }
            maskToIdx.put(mask, i);
        }

        for (Map.Entry<Integer, Integer> e1 : maskToIdx.entrySet()) {
            for (Map.Entry<Integer, Integer> e2 : maskToIdx.entrySet()) {
                if ((e1.getKey() & e2.getKey()) == 0) {
                    int i = e1.getValue();
                    int j = e2.getValue();
                    return i < j ? List.of(i, j) : List.of(j, i);
                }
            }
        }
        return List.of();
    }
}

没有人能只依靠天分成功。上帝给予了天分,勤奋将天分变为天才。”——沃兹尼亚尔

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值