一、题目
1、题目描述
给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。
2、基础框架
- C++版本给出的基础框架如下:
3、原题链接
https://leetcode.cn/problems/set-matrix-zeroes/submissions/
二、解题报告
1、思路分析
1.1 暴力解法
(
1
)
(1)
(1)遍历数组,用两个set容器分别记录0元素的行和列。
(
2
)
(2)
(2)分别遍历set容器,将出现的行和列上所有值置为0。
1.2 原地解法
(
1
)
(1)
(1)用第一行和第一列来记录所有行和列中是否出现0元素。
(
2
)
(2)
(2)比如matrix[2][3]值为0,那么就将matrix[2][0]和matrix[0][3]置为0。
(
3
)
(3)
(3)第一次遍历之后,第一行中的0元素的所在列应全部置为0,第一列中的0元素所在行应全部置为0。第二次遍历非第一行和非第一列的元素,根据当前值所在行的第一列或所在列的第一行的值是否为0,来判断是否置0.
(
4
)
(4)
(4)以上思路存在一个问题就是原数组第一行和第一列也可能存在0。如果第一行存在0,应将第一行全部置为0,如果第一列存在0,应将第一列全部置为0,所以我们需要用两个标记变量在第一次遍历时分别记录原始第一行和第一列是否出现0。
(
5
)
(5)
(5)最后根据标记变量的值判断是否将第一行或第一列的值全部置为0。
2、时间复杂度
暴力解法:时间复杂度O(mn),空间复杂度O(max(m,n))
原地解法:时间复杂度O(mn),空间复杂度O(1)
3、代码详解
暴力解法
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix) {
set<int> row;
set<int> col;
for (int i = 0;i < matrix.size(); i++) {
for (int j = 0;j < matrix[0].size();j++) {
if (matrix[i][j] == 0) {
row.insert(i);
col.insert(j);
}
}
}
for (set<int>::iterator it = row.begin(); it != row.end(); it++) {
int x = *it;
for (int i = 0; i < matrix[x].size(); i++) {
matrix[x][i] = 0;
}
}
for (set<int>::iterator it = col.begin(); it != col.end(); it++) {
int x = *it;
for (int i = 0; i < matrix.size(); i++) {
matrix[i][x] = 0;
}
}
}
};
class Solution {
public void setZeroes(int[][] matrix) {
boolean row = false;
boolean col = false;
for (int i=0;i<matrix.length;i++) {
for (int j=0;j<matrix[0].length;j++){
if (matrix[i][j] == 0) {
if(i == 0) {
row = true;
}
if(j == 0) {
col = true;
}
matrix[i][0] = matrix[0][j] = 0;
}
}
}
for (int i=1;i<matrix.length;i++){
for(int j=1;j<matrix[0].length;j++) {
if(matrix[i][0]==0||matrix[0][j]==0){
matrix[i][j] = 0;
}
}
}
if (row) {
for (int i=0;i<matrix[0].length;i++){
matrix[0][i] = 0;
}
}
if (col) {
for (int j=0;j<matrix.length;j++){
matrix[j][0] = 0;
}
}
}
}
三、本题小知识
1.C++ set容器的使用,添加元素insert(value)。遍历元素set::iterator it