1. 程式人生 > >leetcode-73- 矩陣置零(set matrix zeroes)-java

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(別人的)

使用固定的空間,原地演算法

其實我們可以利用首行首列來表示這一行,這一列有沒有出現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; } }