Skip to content

Commit 6d4d393

Browse files
committed
feat: add Flood Fill
1 parent a7ad8ba commit 6d4d393

File tree

7 files changed

+199
-1
lines changed

7 files changed

+199
-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": "flood_fill",
3+
"solution_class_name": "Solution",
4+
"problem_number": "733",
5+
"problem_title": "Flood Fill",
6+
"difficulty": "Easy",
7+
"topics": "Array, Depth-First Search, Breadth-First Search, Matrix",
8+
"tags": ["grind-75"],
9+
"readme_description": "You are given an image represented by an `m x n` grid of integers `image`, where `image[i][j]` represents the pixel value of the image. You are also given three integers `sr`, `sc`, and `color`. Your task is to perform a **flood fill** on the image starting from the pixel `image[sr][sc]`.\n\nTo perform a **flood fill**:\n\n1. Begin with the starting pixel and change its color to `color`.\n2. Perform the same process for each pixel that is **directly adjacent** (pixels that share a side with the original pixel, either horizontally or vertically) and shares the **same color** as the starting pixel.\n3. Keep **repeating** this process by checking neighboring pixels of the *updated* pixels and modifying their color if it matches the original color of the starting pixel.\n4. The process **stops** when there are **no more** adjacent pixels of the original color to update.\n\nReturn the **modified** image after performing the flood fill.",
10+
"readme_examples": [
11+
{
12+
"content": "![Example 1](https://assets.leetcode.com/uploads/2021/06/01/flood1-grid.jpg)\n\n```\nInput: image = [[1,1,1],[1,1,0],[1,0,1]], sr = 1, sc = 1, color = 2\nOutput: [[2,2,2],[2,2,0],[2,0,1]]\n```\n**Explanation:** From the center of the image with position `(sr, sc) = (1, 1)` (i.e., the red pixel), all pixels connected by a path of the same color as the starting pixel (i.e., the blue pixels) are colored with the new color. Note the bottom corner is not colored 2, because it is not horizontally or vertically connected to the starting pixel."
13+
},
14+
{
15+
"content": "```\nInput: image = [[0,0,0],[0,0,0]], sr = 0, sc = 0, color = 0\nOutput: [[0,0,0],[0,0,0]]\n```\n**Explanation:** The starting pixel is already colored with 0, which is the same as the target color. Therefore, no changes are made to the image."
16+
}
17+
],
18+
"readme_constraints": "- `m == image.length`\n- `n == image[i].length`\n- `1 <= m, n <= 50`\n- `0 <= image[i][j], color < 2^16`\n- `0 <= sr < m`\n- `0 <= sc < n`",
19+
"readme_additional": "",
20+
"solution_imports": "",
21+
"solution_methods": [
22+
{
23+
"name": "flood_fill",
24+
"parameters": "image: list[list[int]], sr: int, sc: int, color: 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": "FloodFill",
31+
"test_helper_methods": [
32+
{ "name": "setup_method", "parameters": "", "body": "self.solution = Solution()" }
33+
],
34+
"test_methods": [
35+
{
36+
"name": "test_flood_fill",
37+
"parametrize": "image, sr, sc, color, expected",
38+
"parametrize_typed": "image: list[list[int]], sr: int, sc: int, color: int, expected: list[list[int]]",
39+
"test_cases": "[([[1, 1, 1], [1, 1, 0], [1, 0, 1]], 1, 1, 2, [[2, 2, 2], [2, 2, 0], [2, 0, 1]]), ([[0, 0, 0], [0, 0, 0]], 0, 0, 0, [[0, 0, 0], [0, 0, 0]]), ([[0, 0, 0], [0, 1, 1]], 1, 1, 1, [[0, 0, 0], [0, 1, 1]]), ([[1, 1, 1], [1, 1, 0], [1, 0, 1]], 1, 1, 1, [[1, 1, 1], [1, 1, 0], [1, 0, 1]])]",
40+
"body": "result = self.solution.flood_fill(image, sr, sc, color)\nassert result == expected"
41+
}
42+
],
43+
"playground_imports": "from solution import Solution",
44+
"playground_test_case": "# Example test case\nimage = [[1, 1, 1], [1, 1, 0], [1, 0, 1]]\nsr = 1\nsc = 1\ncolor = 2\nexpected = [[2, 2, 2], [2, 2, 0], [2, 0, 1]]",
45+
"playground_execution": "result = Solution().flood_fill(image, sr, sc, color)\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 ?= contains_duplicate
2+
PROBLEM ?= flood_fill
33
FORCE ?= 0
44
COMMA := ,
55

leetcode/flood_fill/README.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Flood Fill
2+
3+
**Difficulty:** Easy
4+
**Topics:** Array, Depth-First Search, Breadth-First Search, Matrix
5+
**Tags:** grind-75
6+
7+
**LeetCode:** [Problem 733](https://leetcode.com/problems/flood-fill/description/)
8+
9+
## Problem Description
10+
11+
You are given an image represented by an `m x n` grid of integers `image`, where `image[i][j]` represents the pixel value of the image. You are also given three integers `sr`, `sc`, and `color`. Your task is to perform a **flood fill** on the image starting from the pixel `image[sr][sc]`.
12+
13+
To perform a **flood fill**:
14+
15+
1. Begin with the starting pixel and change its color to `color`.
16+
2. Perform the same process for each pixel that is **directly adjacent** (pixels that share a side with the original pixel, either horizontally or vertically) and shares the **same color** as the starting pixel.
17+
3. Keep **repeating** this process by checking neighboring pixels of the _updated_ pixels and modifying their color if it matches the original color of the starting pixel.
18+
4. The process **stops** when there are **no more** adjacent pixels of the original color to update.
19+
20+
Return the **modified** image after performing the flood fill.
21+
22+
## Examples
23+
24+
### Example 1:
25+
26+
![Example 1](https://assets.leetcode.com/uploads/2021/06/01/flood1-grid.jpg)
27+
28+
```
29+
Input: image = [[1,1,1],[1,1,0],[1,0,1]], sr = 1, sc = 1, color = 2
30+
Output: [[2,2,2],[2,2,0],[2,0,1]]
31+
```
32+
33+
**Explanation:** From the center of the image with position `(sr, sc) = (1, 1)` (i.e., the red pixel), all pixels connected by a path of the same color as the starting pixel (i.e., the blue pixels) are colored with the new color. Note the bottom corner is not colored 2, because it is not horizontally or vertically connected to the starting pixel.
34+
35+
### Example 2:
36+
37+
```
38+
Input: image = [[0,0,0],[0,0,0]], sr = 0, sc = 0, color = 0
39+
Output: [[0,0,0],[0,0,0]]
40+
```
41+
42+
**Explanation:** The starting pixel is already colored with 0, which is the same as the target color. Therefore, no changes are made to the image.
43+
44+
## Constraints
45+
46+
- `m == image.length`
47+
- `n == image[i].length`
48+
- `1 <= m, n <= 50`
49+
- `0 <= image[i][j], color < 2^16`
50+
- `0 <= sr < m`
51+
- `0 <= sc < n`

leetcode/flood_fill/__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\nimage = [[1, 1, 1], [1, 1, 0], [1, 0, 1]]\nsr = 1\nsc = 1\ncolor = 2\nexpected = [[2, 2, 2], [2, 2, 0], [2, 0, 1]]"]
18+
},
19+
{
20+
"cell_type": "code",
21+
"execution_count": null,
22+
"id": "execute",
23+
"metadata": {},
24+
"outputs": [],
25+
"source": ["result = Solution().flood_fill(image, sr, sc, color)\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+
}

leetcode/flood_fill/solution.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class Solution:
2+
# Time: O(m*n)
3+
# Space: O(m*n)
4+
def flood_fill(self, image: list[list[int]], sr: int, sc: int, color: int) -> list[list[int]]:
5+
original = image[sr][sc]
6+
if original == color:
7+
return image
8+
9+
def dfs(r: int, c: int) -> None:
10+
if r < 0 or r >= len(image) or c < 0 or c >= len(image[0]) or image[r][c] != original:
11+
return
12+
image[r][c] = color
13+
for dr, dc in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
14+
dfs(r + dr, c + dc)
15+
16+
dfs(sr, sc)
17+
return image

leetcode/flood_fill/tests.py

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

0 commit comments

Comments
 (0)