[LeetCode] 73. Set Matrix Zeroes 矩阵赋零
Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in-place.
Example 1:
Input: [ [1,1,1], [1,0,1], [1,1,1] ] Output: [ [1,0,1], [0,0,0], [1,0,1] ]
Example 2:
Input: [ [0,1,2,0], [3,4,5,2], [1,3,1,5] ] Output: [ [0,0,0,0], [0,4,5,0], [0,3,1,0] ]
Follow up:
- A straight forward solution using O(mn) space is probably a bad idea.
- A simple improvement uses O(m + n) space, but still not the best solution.
- Could you devise a constant space solution?
给一个m x n的矩阵,如果一个元素是0,就把它所在的行和列都设成0,用in place做。
解法1: 新建一个矩阵,然后一行一行的扫,只要有0,就将新建的矩阵的对应行全赋0,行扫完再扫列,然后把更新完的矩阵赋给matrix。空间复杂度为O(mn)。
解法2: 用一个长度为m的一维数组记录各行中是否有0,用一个长度为n的一维数组记录各列中是否有0,最后直接更新matrix数组即可。空间复杂度为O(m+n),
解法3: 这道题要求用常数级空间复杂度O(1),不能新建数组,就用原数组的第一行第一列来记录各行各列是否有0.
- 先扫描第一行第一列,如果有0,则将各自的flag设置为true
- 然后扫描除去第一行第一列的整个数组,如果有0,则将对应的第一行和第一列的数字赋0
- 再次遍历除去第一行第一列的整个数组,如果对应的第一行和第一列的数字有一个为0,则将当前值赋0
- 最后根据第一行第一列的flag来更新第一行第一列
时间复杂度是O(m*n), 三种方法都一样,需要进行两次扫描,一次确定行列置0情况,一次对矩阵进行实际的置0操作。
Java:
void setZeroes(vector<vector<int> > &matrix) { int col0 = 1, rows = matrix.size(), cols = matrix[0].size(); for (int i = 0; i < rows; i++) { if (matrix[i][0] == 0) col0 = 0; for (int j = 1; j < cols; j++) if (matrix[i][j] == 0) matrix[i][0] = matrix[0][j] = 0; } for (int i = rows - 1; i >= 0; i--) { for (int j = cols - 1; j >= 1; j--) if (matrix[i][0] == 0 || matrix[0][j] == 0) matrix[i][j] = 0; if (col0 == 0) matrix[i][0] = 0; } }
Java:
public void setZeroes(int[][] matrix) { boolean fr = false,fc = false; for(int i = 0; i < matrix.length; i++) { for(int j = 0; j < matrix[0].length; j++) { if(matrix[i][j] == 0) { if(i == 0) fr = true; if(j == 0) fc = true; matrix[0][j] = 0; matrix[i][0] = 0; } } } for(int i = 1; i < matrix.length; i++) { for(int j = 1; j < matrix[0].length; j++) { if(matrix[i][0] == 0 || matrix[0][j] == 0) { matrix[i][j] = 0; } } } if(fr) { for(int j = 0; j < matrix[0].length; j++) { matrix[0][j] = 0; } } if(fc) { for(int i = 0; i < matrix.length; i++) { matrix[i][0] = 0; } } }
Java:
public class Solution { public void setZeroes(int[][] matrix) { boolean firstRowZero = false; boolean firstColumnZero = false; //set first row and column zero or not for(int i=0; i<matrix.length; i++){ if(matrix[i][0] == 0){ firstColumnZero = true; break; } } for(int i=0; i<matrix[0].length; i++){ if(matrix[0][i] == 0){ firstRowZero = true; break; } } //mark zeros on first row and column for(int i=1; i<matrix.length; i++){ for(int j=1; j<matrix[0].length; j++){ if(matrix[i][j] == 0){ matrix[i][0] = 0; matrix[0][j] = 0; } } } //use mark to set elements for(int i=1; i<matrix.length; i++){ for(int j=1; j<matrix[0].length; j++){ if(matrix[i][0] == 0 || matrix[0][j] == 0){ matrix[i][j] = 0; } } } //set first column and row if(firstColumnZero){ for(int i=0; i<matrix.length; i++) matrix[i][0] = 0; } if(firstRowZero){ for(int i=0; i<matrix[0].length; i++) matrix[0][i] = 0; } } }
Java:
public void setZeroes(int[][] matrix) { if(matrix==null || matrix.length==0 || matrix[0].length==0) return; boolean rowFlag = false; boolean colFlag = false; for(int i=0;i<matrix.length;i++) { if(matrix[i][0]==0) { colFlag = true; break; } } for(int i=0;i<matrix[0].length;i++) { if(matrix[0][i]==0) { rowFlag = true; break; } } for(int i=1;i<matrix.length;i++) { for(int j=1;j<matrix[0].length;j++) { if(matrix[i][j]==0) { matrix[i][0] = 0; matrix[0][j] = 0; } } } for(int i=1;i<matrix.length;i++) { for(int j=1;j<matrix[0].length;j++) { if(matrix[i][0]==0 || matrix[0][j]==0) matrix[i][j] = 0; } } if(colFlag) { for(int i=0;i<matrix.length;i++) { matrix[i][0] = 0; } } if(rowFlag) { for(int i=0;i<matrix[0].length;i++) { matrix[0][i] = 0; } } }
Python:
class Solution: # @param matrix, a list of lists of integers # RETURN NOTHING, MODIFY matrix IN PLACE. def setZeroes(self, matrix): first_col = reduce(lambda acc, i: acc or matrix[i][0] == 0, xrange(len(matrix)), False) first_row = reduce(lambda acc, j: acc or matrix[0][j] == 0, xrange(len(matrix[0])), False) for i in xrange(1, len(matrix)): for j in xrange(1, len(matrix[0])): if matrix[i][j] == 0: matrix[i][0], matrix[0][j] = 0, 0 for i in xrange(1, len(matrix)): for j in xrange(1, len(matrix[0])): if matrix[i][0] == 0 or matrix[0][j] == 0: matrix[i][j] = 0 if first_col: for i in xrange(len(matrix)): matrix[i][0] = 0 if first_row: for j in xrange(len(matrix[0])): matrix[0][j] = 0
Python:
class Solution: # @param {integer[][]} matrix # @return {void} Do not return anything, modify matrix in-place instead. def setZeroes(self, matrix): m = len(matrix) if m == 0: return n = len(matrix[0]) row_zero = False for i in range(m): if matrix[i][0] == 0: row_zero = True col_zero = False for j in range(n): if matrix[0][j] == 0: col_zero = True for i in range(1, m): for j in range(1, n): if matrix[i][j] == 0: matrix[i][0] = 0 matrix[0][j] = 0 for i in range(1, m): if matrix[i][0] == 0: for j in range(1, n): matrix[i][j] = 0 for j in range(1, n): if matrix[0][j] == 0: for i in range(1, m): matrix[i][j] = 0 if col_zero: for j in range(n): matrix[0][j] = 0 if row_zero: for i in range(m): matrix[i][0] = 0
C++:
class Solution { public: void setZeroes(vector<vector<int> > &matrix) { if (matrix.empty() || matrix[0].empty()) return; int m = matrix.size(), n = matrix[0].size(); bool rowZero = false, colZero = false; for (int i = 0; i < m; ++i) { if (matrix[i][0] == 0) colZero = true; } for (int i = 0; i < n; ++i) { if (matrix[0][i] == 0) rowZero = true; } for (int i = 1; i < m; ++i) { for (int j = 1; j < n; ++j) { if (matrix[i][j] == 0) { matrix[0][j] = 0; matrix[i][0] = 0; } } } for (int i = 1; i < m; ++i) { for (int j = 1; j < n; ++j) { if (matrix[0][j] == 0 || matrix[i][0] == 0) { matrix[i][j] = 0; } } } if (rowZero) { for (int i = 0; i < n; ++i) matrix[0][i] = 0; } if (colZero) { for (int i = 0; i < m; ++i) matrix[i][0] = 0; } } };