版权声明:此文章为许诗宇所写,如需转载,请写下转载文章的地址 https://blog.csdn.net/xushiyu1996818/article/details/83578056
题目及测试
package pid073;
/*矩阵置零
给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0。请使用原地算法。
示例 1:
输入:
[
[1,1,1],
[1,0,1],
[1,1,1]
]
输出:
[
[1,0,1],
[0,0,0],
[1,0,1]
]
示例 2:
输入:
[
[0,1,2,0],
[3,4,5,2],
[1,3,1,5]
]
输出:
[
[0,0,0,0],
[0,4,5,0],
[0,3,1,0]
]
进阶:
一个直接的解决方案是使用 O(mn) 的额外空间,但这并不是一个好的解决方案。
一个简单的改进方案是使用 O(m + n) 的额外空间,但这仍然不是最好的解决方案。
你能想出一个常数空间的解决方案吗?
*/
public class main {
public static void main(String[] args) {
int[][][] testTable = {{{1,1,1},{1,0,1},{1,1,1}},{{0,1,2,0},{3,4,5,2},{3,4,5,2}}};
for (int i=0;i<testTable.length;i++) {
test(testTable[i]);
}
}
private static void test(int[][] ito) {
Solution solution = new Solution();
int rtn;
long begin = System.currentTimeMillis();
System.out.println("ito=");
for(int i=0;i<ito.length;i++){
for(int j=0;j<ito[0].length;j++){
System.out.print(ito[i][j]+" ");
}
System.out.println();
}
solution.setZeroes(ito);//执行程序
long end = System.currentTimeMillis();
System.out.println("rtn=");
for(int i=0;i<ito.length;i++){
for(int j=0;j<ito[0].length;j++){
System.out.print(ito[i][j]+" ");
}
System.out.println();
}
System.out.println();
System.out.println("耗时:" + (end - begin) + "ms");
System.out.println("-------------------");
}
}
解法1(成功,2ms)
使用o(m+n)的空间,创立row0和col0数组,为对于行列是否有0
先遍历一遍,得到0,将对于的row0[i] 和col0[j]设为true
然后遍历row0和col0,使对应行列全设为0
package pid073;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public class Solution {
public void setZeroes(int[][] matrix) {
int rows=matrix.length;
if(rows==0){
return;
}
int cols=matrix[0].length;
if(cols==0){
return;
}
boolean[] row0=new boolean[rows];
boolean[] col0=new boolean[cols];
for(int i=0;i<rows;i++){
for(int j=0;j<cols;j++){
if(matrix[i][j]==0){
row0[i]=true;
col0[j]=true;
//System.out.println("i="+i+"j="+j);
}
}
}
for(int i=0;i<rows;i++){
if(row0[i]==true){
for(int j=0;j<cols;j++){
matrix[i][j]=0;
//System.out.println("i="+i+"j="+j);
}
}
}
for(int j=0;j<cols;j++){
//System.out.println("col0="+j+col0[j]);
if(col0[j]==true){
for(int i=0;i<rows;i++){
matrix[i][j]=0;
//System.out.println("i="+i+"j="+j);
}
}
}
}
}
解法2(别人的)
使用固定的空间,原地算法
其实我们可以利用首行首列来表示这一行,这一列有没有出现0,于此同时,需要使用两个变量,来标记首行和首列是否需要置0.因此大致思路是:
1、扫描首行,首列,记录其是否需要置0,
2、扫描每一行,每一列,如果出现0了,那么在对应的首行或首列标记(比如使用0),没有的话标记另一个(比如1)
3、当遍历玩后,根据标记的数据回过去,将对应的行货列置0.
public class Solution { /**
* 因为不能使用多余空间,所以将首行和首列作为标记,标记对应的行列是否需要清0
*
* 因为首行首列用作标记,所以需要提前保存下首行首列的0的情况,使用两个变量来保存
* */ public void setZeroes(int[][] matrix) { int n=matrix.length,m=matrix[0].length; boolean fCol=false,fRow=false;
//首行首列要用作保存,所以先预先技术一下
for(int i=0;i<n;i++){
if(matrix[i][0]==0){
fCol=true; break; }
}
for(int i=0;i<m;i++){
if(matrix[0][i]==0){ fRow=true; break; } }
for(int i=1;i<n;i++){
for(int j=0;j<m;j++){
if(matrix[i][j]==0){ matrix[i][0]=0; break; } } }
for(int j=1;j<m;j++){
for(int i=0;i<n;i++){
if(matrix[i][j]==0){ matrix[0][j]=0; break; } } }
//填充
for(int i=1;i<n;i++){
if(matrix[i][0]==0){
for(int j=0;j<m;j++){
matrix[i][j]=0; } } }
for(int j=1;j<m;j++){
if(matrix[0][j]==0){
for(int i=0;i<n;i++){ matrix[i][j]=0; } } }
if(fCol)
for(int i=0;i<n;i++)
matrix[i][0]=0;
if(fRow)
for(int i=0;i<m;i++)
matrix[0][i]=0; } }