0
点赞
收藏
分享

微信扫一扫

每天一道算法题(27)

给定一个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;
}
}

}
}
举报

相关推荐

0 条评论