|
| 1 | +# https://leetcode.com/problems/set-matrix-zeroes/ |
| 2 | + |
| 3 | +from typing import List |
| 4 | + |
| 5 | +class Solution: |
| 6 | + def setZeroes_slow(self, matrix: List[List[int]]) -> None: |
| 7 | + """ |
| 8 | + Do not return anything, modify matrix in-place instead. |
| 9 | +
|
| 10 | + [Complexity] |
| 11 | + - TC: O(m * n * (m + n)) -> too slow... |
| 12 | + - SC: O(1) |
| 13 | +
|
| 14 | + [Approach] |
| 15 | + 다음의 두 단계를 inplace로 수행한다. |
| 16 | + 1. 모든 cell을 순회하며, 0을 발견하면 해당 row와 column의 값을 (0인 cell을 제외하고) 모두 #로 바꾼다. |
| 17 | + 2. 다시 모든 cell을 순회하며, #을 모두 0으로 바꾼다. |
| 18 | + """ |
| 19 | + |
| 20 | + m, n = len(matrix), len(matrix[0]) |
| 21 | + |
| 22 | + def set_row_col(r, c): |
| 23 | + for _r in range(m): |
| 24 | + # 0이 아닌 경우에만 "#"으로 바꿔야 함 ** |
| 25 | + if matrix[_r][c] != 0: |
| 26 | + matrix[_r][c] = "#" |
| 27 | + |
| 28 | + for _c in range(n): |
| 29 | + if matrix[r][_c] != 0: |
| 30 | + matrix[r][_c] = "#" |
| 31 | + |
| 32 | + # 1. 0을 발견하면 해당 row & column을 "#"으로 바꾸기 |
| 33 | + for r in range(m): |
| 34 | + for c in range(n): |
| 35 | + if matrix[r][c] == 0: |
| 36 | + # row & column을 "#"으로 바꾸기 |
| 37 | + set_row_col(r, c) |
| 38 | + |
| 39 | + # 2. "#"을 모두 0으로 바꾸기 |
| 40 | + for r in range(m): |
| 41 | + for c in range(n): |
| 42 | + if matrix[r][c] == "#": |
| 43 | + matrix[r][c] = 0 |
| 44 | + |
| 45 | + def setZeroes(self, matrix: List[List[int]]) -> None: |
| 46 | + """ |
| 47 | + Do not return anything, modify matrix in-place instead. |
| 48 | +
|
| 49 | + [Complexity] |
| 50 | + - TC: O(m * n) |
| 51 | + - SC: O(1) |
| 52 | +
|
| 53 | + [Approach] |
| 54 | + matrix의 첫 번째 row와 column을 flag 기록 용도로 사용한다면, space를 O(1)로 유지하면서 time도 최적화할 수 있다. |
| 55 | + - 첫 번째 row: 각 column에 0이 있었다면, 해당 column의 칸에 0으로 기록 |
| 56 | + - 첫 번째 column: 각 row에 0이 있었다면, 해당 row의 칸에 0으로 기록 |
| 57 | + 이렇게 첫 번째 row와 column을 flag 기록용으로 쓰기 전에, 해당 row와 column에 0이 있었는지 여부를 미리 확인해야 함에 유의한다. |
| 58 | + 전체 흐름은 다음과 같다: |
| 59 | + 1. 첫 번째 row와 column에 0이 존재하는지 여부 확인 |
| 60 | + 2. 두 번째 row와 column 부터 0이 존재하는 칸에 대해 첫 번째 row와 column에 flag 기록 |
| 61 | + 3. 첫 번째 row와 column의 flag 값을 기반으로, 0 채우기 |
| 62 | + 4. 1번에서 구해둔 값으로도 0 채우기 |
| 63 | + """ |
| 64 | + |
| 65 | + m, n = len(matrix), len(matrix[0]) |
| 66 | + |
| 67 | + # 1. 첫 번째 row와 column에 0이 존재하는지 여부 확인 |
| 68 | + has_zero_in_first_row = any(matrix[0][_c] == 0 for _c in range(n)) |
| 69 | + has_zero_in_first_col = any(matrix[_r][0] == 0 for _r in range(m)) |
| 70 | + |
| 71 | + # 2. 두 번째 row와 column 부터 0이 존재하는 칸에 대해 첫 번째 row와 column에 flag 기록 |
| 72 | + for r in range(1, m): |
| 73 | + for c in range(1, n): |
| 74 | + if matrix[r][c] == 0: |
| 75 | + matrix[0][c] = 0 |
| 76 | + matrix[r][0] = 0 |
| 77 | + |
| 78 | + # 3. 첫 번째 row와 column의 flag 값을 기반으로, 0 채우기 |
| 79 | + for r in range(1, m): |
| 80 | + for c in range(1, n): |
| 81 | + if matrix[0][c] == 0 or matrix[r][0] == 0: |
| 82 | + matrix[r][c] = 0 |
| 83 | + |
| 84 | + # 4. 1번에서 구해둔 값으로도 0 채우기 |
| 85 | + if has_zero_in_first_row: |
| 86 | + for _c in range(n): |
| 87 | + matrix[0][_c] = 0 |
| 88 | + |
| 89 | + if has_zero_in_first_col: |
| 90 | + for _r in range(m): |
| 91 | + matrix[_r][0] = 0 |
0 commit comments