Skip to content

Commit 197c64b

Browse files
committed
feat: add 01 Matrix
1 parent a99f4c4 commit 197c64b

File tree

7 files changed

+208
-1
lines changed

7 files changed

+208
-1
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{
2+
"problem_name": "zero_one_matrix",
3+
"solution_class_name": "Solution",
4+
"problem_number": "542",
5+
"problem_title": "01 Matrix",
6+
"difficulty": "Medium",
7+
"topics": "Array, Dynamic Programming, Breadth-First Search, Matrix",
8+
"tags": ["grind-75"],
9+
"readme_description": "Given an `m x n` binary matrix `mat`, return the distance of the nearest `0` for each cell.\n\nThe distance between two cells sharing a common edge is `1`.",
10+
"readme_examples": [
11+
{
12+
"content": "![Example 1](https://assets.leetcode.com/uploads/2021/04/24/01-1-grid.jpg)\n\n```\nInput: mat = [[0,0,0],[0,1,0],[0,0,0]]\nOutput: [[0,0,0],[0,1,0],[0,0,0]]\n```"
13+
},
14+
{
15+
"content": "![Example 2](https://assets.leetcode.com/uploads/2021/04/24/01-2-grid.jpg)\n\n```\nInput: mat = [[0,0,0],[0,1,0],[1,1,1]]\nOutput: [[0,0,0],[0,1,0],[1,2,1]]\n```"
16+
}
17+
],
18+
"readme_constraints": "- `m == mat.length`\n- `n == mat[i].length`\n- `1 <= m, n <= 10^4`\n- `1 <= m * n <= 10^4`\n- `mat[i][j]` is either `0` or `1`\n- There is at least one `0` in `mat`",
19+
"readme_additional": "**Note:** This question is the same as 1765: [Map of Highest Peak](https://leetcode.com/problems/map-of-highest-peak/)",
20+
"solution_imports": "",
21+
"solution_methods": [
22+
{
23+
"name": "update_matrix",
24+
"parameters": "mat: list[list[int]]",
25+
"return_type": "list[list[int]]",
26+
"dummy_return": "[]"
27+
}
28+
],
29+
"test_imports": "import pytest\nfrom leetcode_py.test_utils import logged_test\nfrom .solution import Solution",
30+
"test_class_name": "ZeroOneMatrix",
31+
"test_helper_methods": [
32+
{ "name": "setup_method", "parameters": "", "body": "self.solution = Solution()" }
33+
],
34+
"test_methods": [
35+
{
36+
"name": "test_update_matrix",
37+
"parametrize": "mat, expected",
38+
"parametrize_typed": "mat: list[list[int]], expected: list[list[int]]",
39+
"test_cases": "[([[0, 0, 0], [0, 1, 0], [0, 0, 0]], [[0, 0, 0], [0, 1, 0], [0, 0, 0]]), ([[0, 0, 0], [0, 1, 0], [1, 1, 1]], [[0, 0, 0], [0, 1, 0], [1, 2, 1]])]",
40+
"body": "result = self.solution.update_matrix(mat)\nassert result == expected"
41+
}
42+
],
43+
"playground_imports": "from solution import Solution",
44+
"playground_test_case": "# Example test case\nmat = [[0, 0, 0], [0, 1, 0], [1, 1, 1]]\nexpected = [[0, 0, 0], [0, 1, 0], [1, 2, 1]]",
45+
"playground_execution": "result = Solution().update_matrix(mat)\nresult",
46+
"playground_assertion": "assert result == expected"
47+
}

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
PYTHON_VERSION = 3.13
2-
PROBLEM ?= implement_queue_using_stacks
2+
PROBLEM ?= zero_one_matrix
33
FORCE ?= 0
44
COMMA := ,
55

leetcode/zero_one_matrix/README.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# 01 Matrix
2+
3+
**Difficulty:** Medium
4+
**Topics:** Array, Dynamic Programming, Breadth-First Search, Matrix
5+
**Tags:** grind-75
6+
7+
**LeetCode:** [Problem 542](https://leetcode.com/problems/zero-one-matrix/description/)
8+
9+
## Problem Description
10+
11+
Given an `m x n` binary matrix `mat`, return the distance of the nearest `0` for each cell.
12+
13+
The distance between two cells sharing a common edge is `1`.
14+
15+
## Examples
16+
17+
### Example 1:
18+
19+
![Example 1](https://assets.leetcode.com/uploads/2021/04/24/01-1-grid.jpg)
20+
21+
```
22+
Input: mat = [[0,0,0],[0,1,0],[0,0,0]]
23+
Output: [[0,0,0],[0,1,0],[0,0,0]]
24+
```
25+
26+
### Example 2:
27+
28+
![Example 2](https://assets.leetcode.com/uploads/2021/04/24/01-2-grid.jpg)
29+
30+
```
31+
Input: mat = [[0,0,0],[0,1,0],[1,1,1]]
32+
Output: [[0,0,0],[0,1,0],[1,2,1]]
33+
```
34+
35+
## Constraints
36+
37+
- `m == mat.length`
38+
- `n == mat[i].length`
39+
- `1 <= m, n <= 10^4`
40+
- `1 <= m * n <= 10^4`
41+
- `mat[i][j]` is either `0` or `1`
42+
- There is at least one `0` in `mat`
43+
44+
**Note:** This question is the same as 1765: [Map of Highest Peak](https://leetcode.com/problems/map-of-highest-peak/)

leetcode/zero_one_matrix/__init__.py

Whitespace-only changes.
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"id": "imports",
7+
"metadata": {},
8+
"outputs": [],
9+
"source": ["from solution import Solution"]
10+
},
11+
{
12+
"cell_type": "code",
13+
"execution_count": null,
14+
"id": "setup",
15+
"metadata": {},
16+
"outputs": [],
17+
"source": ["# Example test case\nmat = [[0, 0, 0], [0, 1, 0], [1, 1, 1]]\nexpected = [[0, 0, 0], [0, 1, 0], [1, 2, 1]]"]
18+
},
19+
{
20+
"cell_type": "code",
21+
"execution_count": null,
22+
"id": "execute",
23+
"metadata": {},
24+
"outputs": [],
25+
"source": ["result = Solution().update_matrix(mat)\nresult"]
26+
},
27+
{
28+
"cell_type": "code",
29+
"execution_count": null,
30+
"id": "test",
31+
"metadata": {},
32+
"outputs": [],
33+
"source": ["assert result == expected"]
34+
}
35+
],
36+
"metadata": {
37+
"kernelspec": {
38+
"display_name": "leetcode-py-py3.13",
39+
"language": "python",
40+
"name": "python3"
41+
},
42+
"language_info": {
43+
"codemirror_mode": {
44+
"name": "ipython",
45+
"version": 3
46+
},
47+
"file_extension": ".py",
48+
"mimetype": "text/x-python",
49+
"name": "python",
50+
"nbconvert_exporter": "python3",
51+
"pygments_lexer": "ipython3",
52+
"version": "3.13.7"
53+
}
54+
},
55+
"nbformat": 4,
56+
"nbformat_minor": 5
57+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from collections import deque
2+
3+
4+
class Solution:
5+
# Time: O(m * n)
6+
# Space: O(m * n)
7+
def update_matrix(self, mat: list[list[int]]) -> list[list[int]]:
8+
UNSEEN = -1
9+
m, n = len(mat), len(mat[0])
10+
queue: deque[tuple[int, int]] = deque()
11+
12+
# Mark 1s as UNSEEN and add all 0s to queue
13+
for i in range(m):
14+
for j in range(n):
15+
if mat[i][j] == 0:
16+
queue.append((i, j))
17+
else:
18+
mat[i][j] = UNSEEN
19+
20+
# BFS from all 0s simultaneously
21+
directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
22+
while queue:
23+
row, col = queue.popleft()
24+
for dr, dc in directions:
25+
r, c = row + dr, col + dc
26+
if 0 <= r < m and 0 <= c < n and mat[r][c] == UNSEEN:
27+
mat[r][c] = mat[row][col] + 1
28+
queue.append((r, c))
29+
30+
return mat

leetcode/zero_one_matrix/tests.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import pytest
2+
3+
from leetcode_py.test_utils import logged_test
4+
5+
from .solution import Solution
6+
7+
8+
class TestZeroOneMatrix:
9+
def setup_method(self):
10+
self.solution = Solution()
11+
12+
@pytest.mark.parametrize(
13+
"mat, expected",
14+
[
15+
([[0, 0, 0], [0, 1, 0], [0, 0, 0]], [[0, 0, 0], [0, 1, 0], [0, 0, 0]]),
16+
([[0, 0, 0], [0, 1, 0], [1, 1, 1]], [[0, 0, 0], [0, 1, 0], [1, 2, 1]]),
17+
([[0]], [[0]]),
18+
([[1, 1, 1], [1, 1, 1], [1, 1, 0]], [[4, 3, 2], [3, 2, 1], [2, 1, 0]]),
19+
([[0, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]], [[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5]]),
20+
(
21+
[[1, 0, 1, 1, 0, 0, 1, 0, 0, 1], [0, 1, 1, 0, 1, 0, 1, 0, 1, 1]],
22+
[[1, 0, 1, 1, 0, 0, 1, 0, 0, 1], [0, 1, 1, 0, 1, 0, 1, 0, 1, 2]],
23+
),
24+
],
25+
)
26+
@logged_test
27+
def test_update_matrix(self, mat: list[list[int]], expected: list[list[int]]):
28+
result = self.solution.update_matrix(mat)
29+
assert result == expected

0 commit comments

Comments
 (0)