给定一个 m x n
的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法(leetcode)
https://leetcode-cn.com/problems/set-matrix-zeroes/
解法一:暴力破解
时间复杂度:O(mn)
空间复杂度:O(m+n)
其实目的就是统计哪几行哪几列的元素需要归0
class Solution {
public void setZeroes(int[][] matrix) {
int n = matrix.length;
int m = matrix[0].length;
HashMap<Integer,Integer> nList = new HashMap<>();
HashMap<Integer,Integer> mList = new HashMap<>();
for(int i = 0 ;i<=n-1;i++){
for(int j = 0;j<=m-1 ;j++){
if(matrix[i][j] == 0){
nList.put(i,0);
mList.put(j,0);
}
}
}
for(int i = 0 ;i<=n-1;i++){
for(int j = 0;j<=m-1 ;j++){
if(nList.containsKey(i) || mList.containsKey(j)){
matrix[i][j] = 0;
}
}
}
}
}
方法二:使用两个标记变量
心得:基于第一个进行优化吧,以后优化算法可以从自身出发,减少空间复杂度
时间复杂度:O(mn)
空间复杂度:O(1)
思路和算法
这个算法的思路和暴力破解差不多,只不过是利用第一行和第一列来记录应该置0的行和列,但是第一个数不能作为记录,因为会同时改变行列,所以使用变量来区分原本是记录第一行第一列的原始0,用第一行第一列记录之后,可以改变所有对应行列的元素,最后再改变第一行第一列即可,减少了空间使用率
class Solution {
public void setZeroes(int[][] matrix) {
int m = matrix.length, n = matrix[0].length;
boolean flagCol0 = false, flagRow0 = false;
for (int i = 0; i < m; i++) {
if (matrix[i][0] == 0) {
flagCol0 = true;
}
}
for (int j = 0; j < n; j++) {
if (matrix[0][j] == 0) {
flagRow0 = true;
}
}
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
if (matrix[i][j] == 0) {
matrix[i][0] = matrix[0][j] = 0;
}
}
}
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;
}
}
}
if (flagCol0) {
for (int i = 0; i < m; i++) {
matrix[i][0] = 0;
}
}
if (flagRow0) {
for (int j = 0; j < n; j++) {
matrix[0][j] = 0;
}
}
}
}