1.8. zero matrix
This commit is contained in:
parent
2e9b3f244f
commit
9794fef144
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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.
|
||||
Loading…
Reference in New Issue