1.8. zero matrix

This commit is contained in:
anebz 2019-04-03 19:05:41 +02:00
parent 2e9b3f244f
commit 9794fef144
2 changed files with 181 additions and 0 deletions

View File

@ -0,0 +1,107 @@
public class QuestionB {
public static void nullifyRow(int[][] matrix, int row) {
for (int j = 0; j < matrix[0].length; j++) {
matrix[row][j] = 0;
}
}
public static void nullifyColumn(int[][] matrix, int col) {
for (int i = 0; i < matrix.length; i++) {
matrix[i][col] = 0;
}
}
public static void setZeros(int[][] matrix) {
boolean rowHasZero = false;
boolean colHasZero = false;
// Check if first row has a zero
for (int j = 0; j < matrix[0].length; j++) {
if (matrix[0][j] == 0) {
rowHasZero = true;
break;
}
}
// Check if first column has a zero
for (int i = 0; i < matrix.length; i++) {
if (matrix[i][0] == 0) {
colHasZero = true;
break;
}
}
// Check for zeros in the rest of the array
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;
}
}
}
// Nullify rows based on values in first column
for (int i = 1; i < matrix.length; i++) {
if (matrix[i][0] == 0) {
nullifyRow(matrix, i);
}
}
// Nullify columns based on values in first row
for (int j = 1; j < matrix[0].length; j++) {
if (matrix[0][j] == 0) {
nullifyColumn(matrix, j);
}
}
// Nullify first row
if (rowHasZero) {
nullifyRow(matrix, 0);
}
// Nullify first column
if (colHasZero) {
nullifyColumn(matrix, 0);
}
}
public static boolean matricesAreEqual(int[][] m1, int[][] m2) {
if (m1.length != m2.length || m1[0].length != m2[0].length) {
return false;
}
for (int k = 0; k < m1.length; k++) {
for (int j = 0; j < m1[0].length; j++) {
if (m1[k][j] != m2[k][j]) {
return false;
}
}
}
return true;
}
public static int[][] cloneMatrix(int[][] matrix) {
int[][] c = new int[matrix.length][matrix[0].length];
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
c[i][j] = matrix[i][j];
}
}
return c;
}
public static void main(String[] args) {
int nrows = 10;
int ncols = 15;
int[][] matrix = AssortedMethods.randomMatrix(nrows, ncols, -10, 10);
AssortedMethods.printMatrix(matrix);
setZeros(matrix);
System.out.println();
AssortedMethods.printMatrix(matrix);
}
}

View File

@ -0,0 +1,74 @@
# 1.8. Zero matrix
## Given an M x N matrix, if an element is 0, make the entire row and column 0
> Example:
```python
imat = [[1,2,0,9],
[4,0,6,8],
[7,8,9,1]]
omat = [[0,0,0,0],
[0,0,0,0],
[7,0,0,1]]
```
## First idea
Intuitivelly I'd find all initial 0 elements, and then 0-ize the respective rows and cols. Only initial 0s must be 0-ized, not new ones. If I have to save all initial zeroes, that's already O(NM). Then iterate through all 0s again, and 0-ize. Which in turn takes O(k(N+M)). If there's a 0 in all rows/cols, the whole matrix is 0 and we can break the loop.
## Hints
1. Find all zeroes first, got it
2. Use O(M+N) space instead of O(NM)? What info do you really need from the list of zeroes?
> example:
```python
list_zeroes = [(0,2), (1,1)]
```
The only info we need is which rows and cols are 'touched', in this case rows:0,1, cols:1,2. Then just go to those rows and delete all cols, and go to all cols and delete all rows.
```python
rows = []
cols = []
for i in range(M):
for j in range(N):
if len(rows) == M or len(cols) == N:
return 0 # zero matrix
if imat[i][j] == 0:
if i not in rows:
rows.append(i)
if j not in cols:
cols.append(j)
for r in rows:
for j in range(N):
imat[r][j] = 0
for c in cols:
for i in range(N):
imat[i][c] = 0
return imat
```
If all rows or all cols are represented, the whole matrix becomes 0.
## Third hint
Reduce additional storage of 0s by using the matrix itself for data storage? In my implementation, space complexity it at most O(M+N) but no idea how to 'flag' these 0es in the matrix itself...
## Solution
Use two arrays to keep track of all the rows with zeros and all the columns with zeros, and then nullify rows and columns based on the values in these arrays. The two arrays are boolean arrays of length N and length M.
Use a bit vector instead of boolean arrays. We can reduce the space to O(1) by using the first column as a replacement for the `row` array and the first row as a replacement for the `column` array.
1. Check if the first row and first column have any zeroes, and set variables `rowHasZero` and `columnHasZero`
2. Iterate through the rest of the matrix, setting imat[i][0] and imat[0][j] to zero whenever there's a zero in imat[i][j].
3. Iterate through the rest of matrix, nullifying row `i` if there's a zero in `imat[i][0]`
4. Iterate through the rest of matrix, nullifying col `j` if there's a zero in `imat[0][j]`
5. Nullify the first row and first column if necessary, based on values from step1.