南陽網(wǎng)站建設公司湖南官網(wǎng)網(wǎng)站推廣軟件
從0開始的秋招刷題路,記錄下所刷每道題的題解,幫助自己回顧總結(jié)
73. 矩陣置零
給定一個 m x n 的矩陣,如果一個元素為 0 ,則將其所在行和列的所有元素都設為 0 。請使用 原地 算法。
示例 1:
輸入:matrix = [[1,1,1],[1,0,1],[1,1,1]]
輸出:[[1,0,1],[0,0,0],[1,0,1]]
示例 2:
輸入:matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]]
輸出:[[0,0,0,0],[0,4,5,0],[0,3,1,0]]
提示:
m == matrix.length
n == matrix[0].length
1 <= m, n <= 200
?231-2^31?231 <= matrix[i][j] <= 231?12^31 - 1231?1
進階:
一個直觀的解決方案是使用 O(mn) 的額外空間,但這并不是一個好的解決方案。
一個簡單的改進方案是使用 O(m + n) 的額外空間,但這仍然不是最好的解決方案。
你能想出一個僅使用常量空間的解決方案嗎?
方法一
思路:用兩個set分別記錄需要置0的行和需要置0的列。第一次遍歷矩陣時,若發(fā)現(xiàn)一個元素為0,則將其行和列值分別加入到兩個set中。第二次遍歷矩陣時,將行set中的行全部置0,將列set中的列全部置0。
public void setZeroes(int[][] matrix) {if(matrix == null || matrix.length == 0)return;int m = matrix.length, n = matrix[0].length;Set<Integer> row = new HashSet<Integer>();Set<Integer> col = new HashSet<Integer>();for(int i = 0; i < m; i++){for(int j = 0; j < n; j++){if(matrix[i][j] == 0){row.add(i);col.add(j);}}}for(int i : row){for(int j = 0; j < n; j++)matrix[i][j] = 0;}for(int j : col){for(int i = 0; i < m; i++)matrix[i][j] = 0;}
}
時間復雜度:O(m×n)
空間復雜度:O(m+n) 最壞情況是矩陣中全部元素為0的情況,這時兩個set的大小分別為m和n。
方法二
思路:不用額外空間,讓首行和首列記錄某列和某行是否有0
算法步驟:
首先用兩個布爾類型變量firstRow和firstCol分別記錄矩陣的首行和首列中是否有0
遍歷除首行和首列外的所有元素,若元素matrix[i][j]為0,則將它對應的首行和首列中的元素matrix[i][0]和matrix[0][j]置為0,意為此行和列后續(xù)需要被置0(由于修改后首行和首列是否有0的信息會被破壞掉,因此需要有之前的步驟一)
遍歷首行和首列,若發(fā)現(xiàn)首行中有元素為0,則將此元素所處的列全部置0,若發(fā)現(xiàn)首列中有元素為0,則將此元素所處的行全部置0。
根據(jù)步驟一的布爾類型變量firstRow和firstCol來判斷首行和首列是否需要被置0。
public void setZeroes(int[][] matrix) {if(matrix == null || matrix.length == 0)return;int m = matrix.length, n = matrix[0].length;boolean firstRow = false, firstCol = false;//步驟一for(int i = 0; i < m; i++){if(matrix[i][0] == 0)firstCol = true;}for(int j = 0; j < n; j++){if(matrix[0][j] == 0)firstRow = true;}//步驟二for(int i = 1; i < m; i++){for(int j = 1; j < n; j++){if(matrix[i][j] == 0){matrix[i][0] = 0;matrix[0][j] = 0;}}}//步驟三for(int i = 1; i < m; i++){if(matrix[i][0] == 0){for(int j = 0; j < n; j++)matrix[i][j] = 0;}}for(int j = 1; j < n; j++){if(matrix[0][j] == 0){for(int i = 0; i < m; i++)matrix[i][j] = 0;}}//步驟四if(firstRow){for(int j = 0; j < n; j++)matrix[0][j] = 0;}if(firstCol){for(int i = 0; i < m; i++)matrix[i][0] = 0;}
}
時間復雜度:O(m×n)
空間復雜度:O(1)