leetcode-73- 矩陣置零(set matrix zeroes)-java
阿新 • • 發佈:2018-11-13
題目及測試
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; } }