Zero Out Rows and Columns Containing a Zero
Solve this ProblemTest Case 1:
Test Case 2:
Test Case 3:
Constraints
- ◆
1 ≤ rows, cols ≤ 20 - ◆
-100 ≤ matrix[i][j] ≤ 100
Try the Dry Run
Don't just read the solution — watch it execute, one step at a time.
| 1 | class Solution { |
| 2 | public int[][] setMatrixZeroes(int[][] matrix) { |
| 3 | int rows = matrix.length, cols = matrix[0].length; |
| 4 | boolean firstRowZero = false, firstColZero = false; |
| 5 | for (int j = 0; j < cols; j++) if (matrix[0][j] == 0) firstRowZero = true; |
| 6 | for (int i = 0; i < rows; i++) if (matrix[i][0] == 0) firstColZero = true; |
| 7 | for (int i = 1; i < rows; i++) { |
| 8 | for (int j = 1; j < cols; j++) { |
| 9 | if (matrix[i][j] == 0) { |
| 10 | matrix[i][0] = 0; |
| 11 | matrix[0][j] = 0; |
| 12 | } |
| 13 | } |
| 14 | } |
| 15 | for (int i = 1; i < rows; i++) { |
| 16 | for (int j = 1; j < cols; j++) { |
| 17 | if (matrix[i][0] == 0 || matrix[0][j] == 0) { |
| 18 | matrix[i][j] = 0; |
| 19 | } |
| 20 | } |
| 21 | } |
| 22 | if (firstRowZero) for (int j = 0; j < cols; j++) matrix[0][j] = 0; |
| 23 | if (firstColZero) for (int i = 0; i < rows; i++) matrix[i][0] = 0; |
| 24 | return matrix; |
| 25 | } |
| 26 | } |
| 27 |
falseCheck row 0 for a zero, since it's about to double as marker storage: firstRowZero = false.
Approach & Solutions
Brute Force
BruteCopy the matrix first, so the ORIGINAL zero positions stay available even after zeroing starts. Scan the copy for zeros — whenever one is found at (i, j), zero out row i and column j in the real matrix. Checking the copy instead of the live matrix is what prevents a newly-created zero from triggering more zeroing than it should. This codebase's judge needs a return value to grade against, so — unlike the classic in-place / void version of this problem — this page's function returns the modified matrix directly.
O(rows·cols)O(rows·cols)1class Solution {
2 public int[][] setMatrixZeroes(int[][] matrix) {
3 int rows = matrix.length, cols = matrix[0].length;
4 int[][] original = new int[rows][cols];
5 for (int i = 0; i < rows; i++) {
6 for (int j = 0; j < cols; j++) {
7 original[i][j] = matrix[i][j];
8 }
9 }
10 for (int i = 0; i < rows; i++) {
11 for (int j = 0; j < cols; j++) {
12 if (original[i][j] == 0) {
13 for (int k = 0; k < cols; k++) matrix[i][k] = 0;
14 for (int k = 0; k < rows; k++) matrix[k][j] = 0;
15 }
16 }
17 }
18 return matrix;
19 }
20}Optimal — First Row/Column as Markers
OptimalInstead of allocating a whole extra matrix, reuse the matrix's own first row and first column as marker storage — matrix[i][0] = 0 means "row i needs zeroing," and matrix[0][j] = 0 means "column j needs zeroing." Since that overwrites the first row/column's own original values, save whether THEY originally contained a zero first (firstRowZero / firstColZero), then restore that at the end.
O(rows·cols)O(1)1class Solution {
2 public int[][] setMatrixZeroes(int[][] matrix) {
3 int rows = matrix.length, cols = matrix[0].length;
4 boolean firstRowZero = false, firstColZero = false;
5 for (int j = 0; j < cols; j++) if (matrix[0][j] == 0) firstRowZero = true;
6 for (int i = 0; i < rows; i++) if (matrix[i][0] == 0) firstColZero = true;
7 for (int i = 1; i < rows; i++) {
8 for (int j = 1; j < cols; j++) {
9 if (matrix[i][j] == 0) {
10 matrix[i][0] = 0;
11 matrix[0][j] = 0;
12 }
13 }
14 }
15 for (int i = 1; i < rows; i++) {
16 for (int j = 1; j < cols; j++) {
17 if (matrix[i][0] == 0 || matrix[0][j] == 0) {
18 matrix[i][j] = 0;
19 }
20 }
21 }
22 if (firstRowZero) for (int j = 0; j < cols; j++) matrix[0][j] = 0;
23 if (firstColZero) for (int i = 0; i < rows; i++) matrix[i][0] = 0;
24 return matrix;
25 }
26}