leetcode-73- 矩阵置零(set matrix zeroes)-java

题目及测试

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(成功,1ms,极快)

使用固定的空间,原地算法

其实我们可以利用首行首列来表示这一行,这一列有没有出现0,于此同时,需要使用2个额外的变量,来标记首行和首列是否需要置0.因此大致思路是:
1、扫描首行和首列,记录其是否需要置0,
2、扫描第二行,第三行。。。,如果出现0了,那么在对应的首行和首列标记设置0
3、当遍历完后,根据标记的数据回过去,将对应的行和列置0.

	public void setZeroes(int[][] matrix) {
        int rows=matrix.length;
        if(rows<=0){
        	return;
        }
        int cols=matrix[0].length;
        if(cols<=0){
        	return;
        }
        // 判断第一行是否为0
        boolean firstRowZero = false;
        for(int i=0;i<cols;i++) {
        	if(matrix[0][i] == 0) {
        		firstRowZero = true;
        		break;
        	}
        }
        // 判断第一列是否为0
        for(int i=0;i<rows;i++) {
        	if(matrix[i][0] == 0) {
        		matrix[0][0] = 0;
        		break;
        	}
        }
        for(int i=1;i<rows;i++){
        	for(int j=1;j<cols;j++){
        		if(matrix[i][j]==0){
        			matrix[i][0] = 0;
        			matrix[0][j] = 0;
        		}
        	}
        }
        
        // 赋值 
        for(int i=1;i<rows;i++) {
        	if(matrix[i][0] == 0) {
        		for(int j=0;j<cols;j++){
            		matrix[i][j] = 0;
            	}
        	}
        }
        for(int j=0;j<cols;j++){
        	if(matrix[0][j] == 0){
            	for(int i=0;i<rows;i++){
            		matrix[i][j] = 0;
            	}
        	}
        }
        
        if(matrix[0][0] == 0) {
        	for(int i=0;i<rows;i++){
        		matrix[i][0] = 0;
        	}
        }
        if(firstRowZero) {
    		for(int j=0;j<cols;j++){
        		matrix[0][j] = 0;
        	}
    	} 	
    	return;
    }	

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值