73. 矩阵置零 - leetcode刷题(C++)

一、题目

73. 矩阵置零

二、分析

  1. 可以采用两个集合,分别记录某一行/某一列是否存在0元素。这种比直接设置两个数组要优化一丢丢。
[[1,1,1],
 [1,0,1],
 [1,1,1]]
set<int> rowzero; // {1},第1行有0
set<int> colzero; // {1},第1列有0

这种情况最坏的空间复杂度还是 O ( m + n ) O(m+n) O(m+n)

  1. 如果第一行和第一列都没有0,如上边例子,那可以用第一行和第一列记录该列或该行有没有0。:要另外记录第一行和第一列有没有0。
1,1,2,3
3,4,0,2
1,0,1,5
--------
1,0,0,3
0,4,0,2
0,0,1,5
用第一行和第一列记录是否有0。
以第二行为例,整个第二行都会被置0,那使用开头的第二行第一列元素来记录完全不会影响它的值。

三、代码

class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        int m(matrix.size()), n(matrix[0].size());
        set<int> rowzero;
        set<int> colzero;
        for(int i = 0; i < m; i ++){
            for(int j = 0 ; j < n ; j++){
                if(matrix[i][j] == 0){
                    rowzero.insert(i);
                    colzero.insert(j);
                }
            }
        }
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                if(rowzero.find(i) != rowzero.end()|| colzero.find(j) != colzero.end()){
                    matrix[i][j] = 0;
                }
            }
        }
    }
};

执行用时:12 ms, 在所有 C++ 提交中击败了94.77%的用户
内存消耗:13.2 MB, 在所有 C++ 提交中击败了27.88%的用户

class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        int m(matrix.size()), n(matrix[0].size());
        bool firstrow_zero = false;
        bool firstcol_zero = false;
        //第一列是否有0
        for(int i = 0; i < m; i ++){
            if(matrix[i][0] == 0){
                firstcol_zero = true;
                break;
            }
        }
        //第一行是否有0
        for(int j = 0 ; j < n ; j++){
            if(matrix[0][j] == 0){
                firstrow_zero = true;
                break;
            }
        }
        //用第一行和第一列记录0元素
        for(int i = 1; i < m; i++){
            for(int j = 1; j < n; j++){
                if(matrix[i][j] == 0){
                    matrix[i][0] = 0;
                    matrix[0][j] = 0;
                }
            }
        }
        //置0操作
        for(int i = 1; i < m; i++){
            for(int j = 1; j < n; j++){
                if(matrix[0][j] == 0 || matrix[i][0] == 0){
                    matrix[i][j] = 0;
                }
            }
        }
        //勿忘第一行和列
        if(firstcol_zero){
            for(int i = 0; i < m; i ++){
                matrix[i][0] = 0;
            }
        }
        if(firstrow_zero){
            for(int j = 0 ; j < n ; j++){
                matrix[0][j] = 0;
            }
        }
    }
};

执行用时:16 ms, 在所有 C++ 提交中击败了80.35%的用户
内存消耗:12.9 MB, 在所有 C++ 提交中击败了75.56%的用户

四、附录

set常用用法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用中的代码片段是一个递归函数,名为beautifulArray,它接受一个整数n作为参数,并返回一个vector<int>类型的结果。这个函数用于生成一个长度为n的漂亮数组,漂亮数组满足以下条件:如果将其划分为两个任意长度的子数组,那么两个子数组的元素之和不相等。 函数的实现思路是通过递归,将问题划分为两个子问题,然后合并子问题的解。首先判断n是否等于1,如果等于1,则直接返回一个包含1的数组。否则,将n减1后的一半传入递归函数beautifulArray,得到一个漂亮数组res1。然后将n的一半传入递归函数beautifulArray,得到另一个漂亮数组res2。最后,将res1中的每个元素乘以2并减去1,然后与res2中的每个元素乘以2合并到结果数组res中。 引用中的代码片段是一个函数,名为translateNum,它接受一个整数num作为参数,并返回一个整数。这个函数用于计算将整数num翻译成字符串的不同方法数。 函数的实现思路是将整数num转换为字符串str,然后创建一个长度为str.size()-1的动态数组dp,用于记录不同位的翻译方法数。然后初始化dp和dp[1]为1,表示前两位数字的翻译方法数。接下来,从第三位数字开始遍历字符串str,如果当前数字与前两位数字可以构成一个在10到25之间的整数,则将dp[i]的值设为dp[i-1]+dp[i-2],表示当前位的翻译方法数为前一位和前两位数字的翻译方法数之和。最后,返回dp最后一个元素的值,即为翻译整数num的不同方法数。 引用中的代码片段是一个函数,名为numberOfArithmeticSlices,它接受一个vector<int>类型的数组nums作为参数,并返回一个整数。这个函数用于计算数组nums中等差子序列的个数。 函数的实现思路是通过动态规划,创建一个与nums长度相同的动态数组dp,用于记录以每个位为结尾的等差子序列的个数。然后遍历数组nums,从第三个元素开始,判断当前元素与前两个元素是否构成等差数列,如果是,则将dp[i]的值设为dp[i-1]加1,表示以当前位为结尾的等差子序列个数为前一位的等差子序列个数加1。最后,返回dp数组中所有元素的和,即为等差子序列的个数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值