import java.util.*; /** * NC352 矩阵置零 * @author d3y1 */ public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param matrix int整型ArrayList<ArrayList<>> * @return int整型ArrayList<ArrayList<>> */ public ArrayList<ArrayList<Integer>> setZeroMatrix (ArrayList<ArrayList<Integer>> matrix) { return solution1(matrix); // return solution2(matrix); // return solution3(matrix); // return solution4(matrix); // return solution44(matrix); // return solution5(matrix); // return solution55(matrix); // return solution555(matrix); } /** * 哈希: HashSet * * 时间复杂度: O(nm) * 空间复杂度: O(n+m) * * @param matrix * @return */ private ArrayList<ArrayList<Integer>> solution1(ArrayList<ArrayList<Integer>> matrix){ int n = matrix.size(); int m = matrix.get(0).size(); HashSet<Integer> rowSet = new HashSet<>(); HashSet<Integer> colSet = new HashSet<>(); for(int row=0; row<n; row++){ for(int col=0; col<m; col++){ if(matrix.get(row).get(col) == 0){ rowSet.add(row); colSet.add(col); } } } // 行置0 // for(int row: rowSet){ // for(int col=0; col<m; col++){ // matrix.get(row).set(col, 0); // } // } // 列置0 // for(int col: colSet){ // for(int row=0; row<n; row++){ // matrix.get(row).set(col, 0); // } // } // 行列置0 for(int row=0; row<n; row++){ for(int col=0; col<m; col++){ if(rowSet.contains(row) || colSet.contains(col)){ matrix.get(row).set(col, 0); } } } return matrix; } /** * 哈希: 标记数组 * * 时间复杂度: O(nm) * 空间复杂度: O(n+m) * * @param matrix * @return */ private ArrayList<ArrayList<Integer>> solution2(ArrayList<ArrayList<Integer>> matrix){ int n = matrix.size(); int m = matrix.get(0).size(); boolean[] rows = new boolean[n]; boolean[] cols = new boolean[m]; for(int row=0; row<n; row++){ for(int col=0; col<m; col++){ if(matrix.get(row).get(col) == 0){ rows[row] = true; cols[col] = true; } } } // 行列置0 for(int row=0; row<n; row++){ for(int col=0; col<m; col++){ if(rows[row] || cols[col]){ matrix.get(row).set(col, 0); } } } return matrix; } /** * 哈希: 两个标记变量 * * 时间复杂度: O(nm) * 空间复杂度: O(1) * * @param matrix * @return */ private ArrayList<ArrayList<Integer>> solution3(ArrayList<ArrayList<Integer>> matrix){ int n = matrix.size(); int m = matrix.get(0).size(); // 标记第一行(row 0) 原来是否有0 boolean flagRow0 = false; // 标记第一列(col 0) 原来是否有0 boolean flagCol0 = false; for(int col=0; col<m; col++){ if(matrix.get(0).get(col) == 0){ flagRow0 = true; break; } } for(int row=0; row<n; row++){ if(matrix.get(row).get(0) == 0){ flagCol0 = true; break; } } // 利用第一行和第一列空间 作为标记数组 for(int row=1; row<n; row++){ for(int col=1; col<m; col++){ if(matrix.get(row).get(col) == 0){ matrix.get(row).set(0, 0); matrix.get(0).set(col, 0); } } } // 根据标记数组 置0 for(int row=1; row<n; row++){ for(int col=1; col<m; col++){ if(matrix.get(row).get(0)==0 || matrix.get(0).get(col)==0){ matrix.get(row).set(col, 0); } } } // 第一行 置0 if(flagRow0){ for(int col=0; col<m; col++){ matrix.get(0).set(col, 0); } } // 第一列 置0 if(flagCol0){ for(int row=0; row<n; row++){ matrix.get(row).set(0, 0); } } return matrix; } /** * 哈希: 一个标记变量 * * 时间复杂度: O(nm) * 空间复杂度: O(1) * * @param matrix * @return */ private ArrayList<ArrayList<Integer>> solution4(ArrayList<ArrayList<Integer>> matrix){ int n = matrix.size(); int m = matrix.get(0).size(); // 标记第一列(col 0) 原来是否有0 boolean flagCol0 = false; for(int row=0; row<n; row++){ if(matrix.get(row).get(0) == 0){ flagCol0 = true; break; } } // 利用第一行和第一列空间 作为标记数组 for(int row=0; row<n; row++){ for(int col=1; col<m; col++){ if(matrix.get(row).get(col) == 0){ // matrix(0,0) 标记第一行(row 0) 原来是否有0 matrix.get(row).set(0, 0); matrix.get(0).set(col, 0); } } } // 根据标记数组 置0; 第一行(row 0)已经作为标记数组, 应该最后置0, 所以降序 for(int row=n-1; row>=0; row--){ for(int col=1; col<m; col++){ if(matrix.get(row).get(0)==0 || matrix.get(0).get(col)==0){ matrix.get(row).set(col, 0); } } } // 第一列 置0 if(flagCol0){ for(int row=0; row<n; row++){ matrix.get(row).set(0, 0); } } return matrix; } /** * 哈希: 一个标记变量 * * 时间复杂度: O(nm) * 空间复杂度: O(1) * * @param matrix * @return */ private ArrayList<ArrayList<Integer>> solution44(ArrayList<ArrayList<Integer>> matrix){ int n = matrix.size(); int m = matrix.get(0).size(); // 标记第一列(col 0) 原来是否有0 boolean flagCol0 = false; // 利用第一行和第一列空间 作为标记数组 for(int row=0; row<n; row++){ // 标记第一列(col 0) 原来是否有0 if(matrix.get(row).get(0) == 0){ flagCol0 = true; } for(int col=1; col<m; col++){ if(matrix.get(row).get(col) == 0){ // matrix(0,0) 标记第一行(row 0) 原来是否有0 matrix.get(row).set(0, 0); matrix.get(0).set(col, 0); } } } // 根据标记数组 置0; 第一行(row 0)已经作为标记数组, 应该最后置0, 所以降序 for(int row=n-1; row>=0; row--){ for(int col=1; col<m; col++){ if(matrix.get(row).get(0)==0 || matrix.get(0).get(col)==0){ matrix.get(row).set(col, 0); } } // 第一列 置0 if(flagCol0){ matrix.get(row).set(0, 0); } } return matrix; } /** * 哈希: 一个标记变量 * * 时间复杂度: O(nm) * 空间复杂度: O(1) * * @param matrix * @return */ private ArrayList<ArrayList<Integer>> solution5(ArrayList<ArrayList<Integer>> matrix){ int n = matrix.size(); int m = matrix.get(0).size(); // 标记第一行(row 0) 原来是否有0 boolean flagRow0 = false; for(int col=0; col<m; col++){ if(matrix.get(0).get(col) == 0){ flagRow0 = true; break; } } // 利用第一行和第一列空间 作为标记数组 for(int row=1; row<n; row++){ for(int col=0; col<m; col++){ if(matrix.get(row).get(col) == 0){ // matrix(0,0) 标记第一列(col 0) 原来是否有0 matrix.get(row).set(0, 0); matrix.get(0).set(col, 0); } } } // 根据标记数组 置0 for(int row=1; row<n; row++){ // 第一列(col 0)已经作为标记数组, 应该最后置0, 所以降序 for(int col=m-1; col>=0; col--){ if(matrix.get(row).get(0)==0 || matrix.get(0).get(col)==0){ matrix.get(row).set(col, 0); } } } // 第一行 置0 if(flagRow0){ for(int col=0; col<m; col++){ matrix.get(0).set(col, 0); } } return matrix; } /** * 哈希: 一个标记变量 * * 时间复杂度: O(nm) * 空间复杂度: O(1) * * @param matrix * @return */ private ArrayList<ArrayList<Integer>> solution55(ArrayList<ArrayList<Integer>> matrix){ int n = matrix.size(); int m = matrix.get(0).size(); // 标记第一行(row 0) 原来是否有0 boolean flagRow0 = false; for(int col=0; col<m; col++){ if(matrix.get(0).get(col) == 0){ flagRow0 = true; break; } } // 利用第一行和第一列空间 作为标记数组 for(int col=0; col<m; col++){ for(int row=1; row<n; row++){ if(matrix.get(row).get(col) == 0){ // matrix(0,0) 标记第一列(col 0) 原来是否有0 matrix.get(row).set(0, 0); matrix.get(0).set(col, 0); } } } // 根据标记数组 置0; 第一列(col 0)已经作为标记数组, 应该最后置0, 所以降序 for(int col=m-1; col>=0; col--){ for(int row=1; row<n; row++){ if(matrix.get(row).get(0)==0 || matrix.get(0).get(col)==0){ matrix.get(row).set(col, 0); } } } // 第一行 置0 if(flagRow0){ for(int col=0; col<m; col++){ matrix.get(0).set(col, 0); } } return matrix; } /** * 哈希: 一个标记变量 * * 时间复杂度: O(nm) * 空间复杂度: O(1) * * @param matrix * @return */ private ArrayList<ArrayList<Integer>> solution555(ArrayList<ArrayList<Integer>> matrix){ int n = matrix.size(); int m = matrix.get(0).size(); // 标记第一行(row 0) 原来是否有0 boolean flagRow0 = false; // 利用第一行和第一列空间 作为标记数组 for(int col=0; col<m; col++){ // 标记第一行(row 0) 原来是否有0 if(matrix.get(0).get(col) == 0){ flagRow0 = true; } for(int row=1; row<n; row++){ if(matrix.get(row).get(col) == 0){ // matrix(0,0) 标记第一列(col 0) 原来是否有0 matrix.get(row).set(0, 0); matrix.get(0).set(col, 0); } } } // 根据标记数组 置0; 第一列(col 0)已经作为标记数组, 应该最后置0, 所以降序 for(int col=m-1; col>=0; col--){ for(int row=1; row<n; row++){ if(matrix.get(row).get(0)==0 || matrix.get(0).get(col)==0){ matrix.get(row).set(col, 0); } } // 第一行 置0 if(flagRow0){ matrix.get(0).set(col, 0); } } return matrix; } }