力扣HOT100刷题记录-矩阵-题解-73.矩阵置零

3 阅读2分钟

矩阵置零(Set Matrix Zeroes)题解

题目描述

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

示例

输入: 
[[1,1,1],
 [1,0,1],
 [1,1,1]]

输出:
[[1,0,1],
 [0,0,0],
 [1,0,1]]

解题思路

使用标记数组技巧,通过两个辅助数组分别记录需要置零的行和列:

  • row[m]: 标记哪些行需要置零
  • col[n]: 标记哪些列需要置零

算法步骤

  1. 第一次遍历:标记所有0元素所在的行和列
  2. 第二次遍历:根据标记数组将对应行列置零

代码实现

#include<iostream>
#include<vector>

using namespace std;

int main(){
    vector<vector<int>> matrix = {{1,1,1},{1,0,1},{1,1,1}};
    
    int m=matrix.size();
    int n=matrix[0].size();

    //标记数组
    vector<bool> row(m,false);
    vector<bool> col(n,false);

    for(int i=0;i<m;i++){
        for(int j=0;j<n;j++){
            if(matrix[i][j]==0){
                row[i]=true;
                col[j]=true;
            }
        }
    }

    for(int i=0;i<m;i++){
        for(int j=0;j<n;j++){
            if(row[i]||col[j]){
                matrix[i][j]=0;
            }
        }
    }

    //输出矩阵
    for(int i=0;i<m;i++){
        for(int j=0;j<n;j++){
            cout<<matrix[i][j]<<" ";
        }
        cout<<endl;
    }


}

执行过程演示

以输入 [[1,1,1],[1,0,1],[1,1,1]]为例:

第一步:标记阶段

  • 遍历发现 matrix[1][1] = 0
  • 标记 row[1] = true, col[1] = true

第二步:置零阶段

  • 遍历所有元素,如果所在行或列被标记,则置零:

    • 第1行所有元素:row[1]为true → 全部置零
    • 第1列所有元素:col[1]为true → 全部置零

最终结果

1 0 1
0 0 0
1 0 1

复杂度分析

  • 时间复杂度:O(m × n),需要遍历矩阵两次
  • 空间复杂度:O(m + n),使用了两个标记数组

优化思路

如果需要O(1)空间复杂度,可以使用矩阵的第一行和第一列作为标记数组,但需要额外处理第一行和第一列本身的0元素情况。