给定一个m*n的矩阵,如果有一个元素是0,就把该元素所在的行和列上的元素全置为0,要求使用原地算法。
拓展:
你的算法有使用额外的空间吗?
一种比较直接的算法是利用O(m,n)的空间,但是这不是一个好的解法
使用简单的改进可以在O(m+n)的空间解决这个问题,但是还不是最佳的解法
你能在常量级的空间复杂度内解决这个问题吗?
解题思路:
法一:用O(m+n)额外空间
两遍扫matrix , 第一遍用集合记录哪些行,哪些列有0,第二遍置0
- 计算二维矩阵的行数和列数
- 循环遍历如果某个数是0,记录其行号和列号,放到hashset中
- 循环遍历将hashset的行号、列号对应的元素置0
import java.util.*;
public class Solution {
public void setZeroes(int[][] matrix) {
HashSet<Integer> row = new HashSet();
HashSet<Integer> col = new HashSet();
for(int i = 0; i< matrix.length;i++){
for(int j =0;j<matrix[0].length;j++){
if(matrix[i][j]==0){
row.add(i);
col.add(j);
}
}
}
for(int i = 0;i < matrix.length;i++){
for(int j = 0;j<matrix[0].length;j++){
if(row.contains(i) || col.contains(j)){
matrix[i][j] = 0;
}
}
}
}
}
法二:O(1)空间——不太好理解,先放着
用matrix第一行和第一列记录该行该列是否有0,作为标志位。但是对于第一行,和第一列要设置一个标志位,为了防止自己这一行(一列)也有0的情况
- 第一列,第一行有0的做标记
- 从第二行,第二列开始,有0的将第一列第一行置0
- 从第二行,第二列开始,第一行第一列有0 的,整行整列都置为0 。
- 当第一行标志位为true,整行为0
- 当第一列标志位为true,整列为0
import java.util.*;
public class Solution {
public void setZeroes(int[][] matrix) {
int m=matrix.length;
int n=matrix[0].length;
boolean col=false;
boolean row=false;
//第一列有0,做标记
for(int i=0;i<m;i++){
if(matrix[i][0]==0){
col=true;
break;
}
}
//第一行有0,做标记
for(int j=0;j<n;j++){
if(matrix[0][j]==0){
row=true;
break;
}
}
//将第一列和第一行置为标记位
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;
}
}
}
//置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;
}
}
}
//第一行有0,第一行都是0
if(row){
for(int j=0;j<n;j++) {
matrix[0][j] = 0;
}
}
//第一列有0,第一列都是0
if(col){
for(int i=0;i<m;i++) {
matrix[i][0] = 0;
}
}
}
}