leetcode每日一题【二进制矩阵中的特殊位置】2022/09/04

一、1582. 二进制矩阵中的特殊位置【简】

一般太简单的题目我就不记录每日一题了,但这道题的一个解法有点意思。

1、题目:

给你一个大小为 rows x cols 的矩阵 mat,其中 mat[i][j] 是 0 或 1,请返回 矩阵 mat 中特殊位置的数目 。

特殊位置 定义:如果 mat[i][j] == 1 并且第 i 行和第 j 列中的所有其他元素均为 0(行和列的下标均 从 0 开始 ),则位置 (i, j) 被称为特殊位置。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/special-positions-in-a-binary-matrix

2、思路一:常规思路

必定是需要遍历整个矩阵才能知道某个位置是否是1,时间复杂度至少是O(rows x cols)。

  • 设置两个数组row[rows]、cow[cows],第一次遍历整个数组,分别记录行/列中1的个数。空间复杂度O(rows+cols);
  • 第二次遍历数组,当mat[i][j]==1时,若row[i] ==1 且 cow[j]==1,说明是特殊位置,记录。

代码:

class Solution {
public:
    int numSpecial(vector<vector<int>>& mat) {
        vector<int> row(mat.size());
        vector<int> col(mat[0].size());
        int res = 0;
        // 第一次遍历
        for(int i =0;i<mat.size();i++){
            for(int j =0;j<mat[0].size();j++){
                if(mat[i][j] == 1){
                    row[i] ++;
                    col[j] ++;
                }
            }
        }
		 // 第二次遍历
        for(int i =0;i<mat.size();i++){
            for(int j =0;j<mat[0].size();j++){
                if(mat[i][j] == 1&& row[i]==1&&col[j]==1){
                    res++;
                } 
            }
        }
        return res;
    }
};

3、思路二

第二种解法来自官方解,可以使空间复杂度为O(1),自己想的时候没想出来怎么可能空间复杂度这么低,看答案的时候发现,其实思路一样,但记录是在原矩阵上进行记录
观察到若某个位置是特殊位置时,其行和列都是只会有1个1。所以可以用原矩阵第一行,去记录某一列中的所有的1,对应的那一行的1的个数,之和,当且仅当这个值为1的时候,这一列才会有一个特殊位置,且特殊位置一列只有一个。

  • 循环所有行,循环行内所有元素求得一行1的个数row1,然后再一次循环行内所有元素,当mat[i][j]==1时,将row1加到第一行mat[0][j]。注意:当第二次循环所有元素的时候,因为第一行可能本来有1,而第一行是为了降低空间复杂度去记录值的,默认应该是0,所以当mat[i][j]==1时让mat[0][j] = row1。
  • 最后循环一次第一行,1的个数即为特殊位置数量。

例子:

例如第二列,mat[1][1]和mat[2][1]都是1,mat[1][1]那一行有2个1,mat[2][1]那一行有2个1,所以mat[0][1] = 4。
在这里插入图片描述
因此第一行[1, 4, 2, 3],该例子只有一个特殊位置。

代码:

class Solution {
public:
    int numSpecial(vector<vector<int>>& mat) {
        int res = 0;
        // 循环所有行
        for(int i = 0;i<mat.size();i++){
            int row1 = 0;
            // 第一次循环i行所有元素,记录行内1数量
            for(int j =0;j<mat[0].size();j++){
                if(mat[i][j]==1){
                    row1 ++;
                }
            }
            // 第二次循环i行所有元素
            for(int j =0;j<mat[0].size();j++){
                if(mat[i][j]==1){
                    if(i == 0){
                        mat[0][j] = row1;
                    }else{
                        mat[0][j] += row1;
                    }
                }
            }
        }
        for(int j =0;j<mat[0].size();j++){
            if(mat[0][j] == 1){
                res++;
            } 
        }
        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值