LeetCode热题100——73.矩阵置零(题目+题解+答案)

题目:

给定一个 mxn 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法**。**

示例 1:

输入: matrix = \[1,1,1,1,0,1,1,1,1]
输出:\[1,0,1,0,0,0,1,0,1]

示例 2:

输入: matrix = \[0,1,2,0,3,4,5,2,1,3,1,5]
输出:\[0,0,0,0,0,4,5,0,0,3,1,0]

提示:

  • m == matrix.length

  • n == matrix[0].length

  • 1 <= m, n <= 200

  • -2^31 <= matrix[i][j] <= 2^31 - 1

题解:

法一:空间复杂度O(m+n)

思路:

遍历一次矩阵,记录下所有0元素所在的行号和列号,然后第二次遍历时,只要当前位置的行号或列号被标记过,就把该位置置为0。

标记信息可以用两个布尔数组实现:一个长度为 m 的 row 数组,rowi = true 表示第 i 行需要清零;另一个长度为 n 的 col 数组,colj = true 表示第 j 列需要清零。

代码:
cpp 复制代码
class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        int m=matrix.size();
        int n=matrix[0].size();
        vector <int> row(m),col(n);
        //第一次遍历:标记需要清零的行和列
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(matrix[i][j]==0) row[i]=col[j]=true;
            }
        }
        //第二次遍历:根据标记修改矩阵
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(row[i]==true||col[j]==true) matrix[i][j]=0;
            }
        }
    }
};

法二:空间复杂度O(1)

思路:

借用矩阵第一行和第一列作为标记数组。

详细步骤:
步骤 1:检查第一行和第一列是否原本包含0
  • 遍历就第一行,如果有元素为 0,则设置 firstRowHasZero = true
  • 遍历第一列,如果有元素为 0,则设置 firstColHasZero = true
步骤 2:用第一行和第一列作为标记数组

遍历矩阵的内部区域(即下标从 1 到 m-1 的行,1 到 n-1 的列):

  • 如果 matrixij == 0,则:
    • 将 matrixi0 设为 0 ------ 标记第 i 行需要清零
    • 将 matrix0j 设为 0 ------ 标记第 j 列需要清零
步骤 3:根据标记清零内部区域

再次遍历内部区域(即下标从 1 到 m-1 的行,1 到 n-1 的列):

如果 matrixi0 == 0 或 matrix0j == 0,则把 matrixij 设为 0。

步骤 4:处理第一行和第一列
  • 如果 firstRowHasZero 为true,则将第一行的所有元素设为 0。
  • 如果 firstColHasZero 为true,则将第一列的所有元素设为 0。
代码:
cpp 复制代码
class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
    int m=matrix.size();
    int n=matrix[0].size();
    bool firstRowHasZero=false;
    bool firstColHasZero=false;
    //步骤1:检查第一行和第一列是否原本包含0
    for(int j=0;j<n;j++){
        if(matrix[0][j]==0) firstRowHasZero=true;
    }
    for(int i=0;i<m;i++){
        if(matrix[i][0]==0) firstColHasZero=true;
    }
    //步骤2:用第一行和第一列作为标记数组
    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;
            } 
        }
    }
    //步骤3:根据标记清零内部区域
    for(int i=1;i<m;i++){
        for(int j=1;j<n;j++){
            if(matrix[i][0]==0||matrix[0][j]==0)
                matrix[i][j]=0;
        }
    }
    //步骤4:处理第一行和第一列
    if(firstColHasZero){
        for(int i=0;i<m;i++) matrix[i][0]=0;
    }
    if(firstRowHasZero){
        for(int j=0;j<n;j++) matrix[0][j]=0;
    }
    }
};
相关推荐
MC皮蛋侠客3 小时前
Google Test 单元测试指南
c++·单元测试·google test
艾莉丝努力练剑4 小时前
【Linux:文件】Ext系列文件系统进阶
linux·运维·服务器·c++·文件系统·文件io·ext
kkeeper~5 小时前
0基础C语言积跬步之数据在内存中的存储
c语言·数据结构·算法
wabs6666 小时前
关于贪心算法的一些自我总结【力扣45.跳跃游戏II】【灵感来源:代码随想录】
算法·贪心算法·复盘
2401_876964136 小时前
【湖北专升本】2026湖北专升本真题PDF+备考资料汇总
数据结构·人工智能·经验分享·深度学习·算法·计算机视觉
basketball6166 小时前
C++ NULL 和 nullptr 区别 以及 nullptr 的核心实现
java·开发语言·c++
嗝o゚7 小时前
CANN GE 算子融合——融合算法与调度策略
算法·昇腾·cann·ge
小江的记录本7 小时前
【JVM虚拟机】垃圾回收GC:垃圾回收算法:标记-清除、标记-复制、标记-整理、分代收集(附《思维导图》+《面试高频考点清单》)
java·jvm·后端·python·算法·安全·面试
Fre丸子_8 小时前
自定义文件夹选取功能
c++
Ulyanov8 小时前
用声明式语法重新定义Python桌面UI:QML+PySide6现代开发入门(一)
开发语言·python·算法·ui·系统仿真·雷达电子对抗仿真