Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 5718c16

Browse files
authoredFeb 20, 2025
feat: add solutions to lc problem: No.0733 (doocs#4087)
No.0733.Flood Fill
1 parent a6a219e commit 5718c16

File tree

15 files changed

+562
-240
lines changed

15 files changed

+562
-240
lines changed
 

‎solution/0700-0799/0722.Remove Comments/README.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -59,20 +59,20 @@ tags:
5959
<strong>解释:</strong> 示例代码可以编排成这样:
6060
/*Test program */
6161
int main()
62-
{
63-
// variable declaration
62+
{
63+
// variable declaration
6464
int a, b, c;
6565
/* This is a test
66-
multiline
67-
comment for
66+
multiline
67+
comment for
6868
testing */
6969
a = b + c;
7070
}
7171
第 1 行和第 6-9 行的字符串 /* 表示块注释。第 4 行的字符串 // 表示行注释。
72-
编排后:
72+
编排后:
7373
int main()
74-
{
75-
74+
{
75+
7676
int a, b, c;
7777
a = b + c;
7878
}</pre>
@@ -106,15 +106,15 @@ a = b + c;
106106

107107
### 方法一:分情况讨论
108108

109-
我们用一个变量 $blockComment$ 来表示当前是否处于块注释中,初始时 $blockComment$ 为 `false`;用一个变量 $t$ 来存储当前行的有效字符。
109+
我们用一个变量 来表示当前是否处于块注释中,初始时 $\textit{blockComment}$ 为 `false`;用一个变量 $t$ 来存储当前行的有效字符。
110110

111111
接下来,遍历每一行,分情况讨论:
112112

113-
如果当前处于块注释中,那么如果当前字符和下一个字符是 `'*/'`,说明块注释结束,我们将 $blockComment$ 置为 `false`,并且跳过这两个字符;否则,我们继续保持块注释状态,不做任何操作;
113+
如果当前处于块注释中,那么如果当前字符和下一个字符是 `'*/'`,说明块注释结束,我们将 $\textit{blockComment}$ 置为 `false`,并且跳过这两个字符;否则,我们继续保持块注释状态,不做任何操作;
114114

115-
如果当前不处于块注释中,那么如果当前字符和下一个字符是 `'/*'`,说明块注释开始,我们将 $blockComment$ 置为 `true`,并且跳过这两个字符;如果当前字符和下一个字符是 `'//'`,那么说明行注释开始,我们直接退出当前行的遍历;否则,说明当前字符是有效字符,我们将其加入 $t$ 中;
115+
如果当前不处于块注释中,那么如果当前字符和下一个字符是 `'/*'`,说明块注释开始,我们将 $\textit{blockComment}$ 置为 `true`,并且跳过这两个字符;如果当前字符和下一个字符是 `'//'`,那么说明行注释开始,我们直接退出当前行的遍历;否则,说明当前字符是有效字符,我们将其加入 $t$ 中;
116116

117-
遍历完当前行后,如果 $blockComment$ 为 `false`,并且 $t$ 不为空,说明当前行是有效行,我们将其加入答案数组中,并且清空 $t$。继续遍历下一行。
117+
遍历完当前行后,如果 $\textit{blockComment}$ 为 `false`,并且 $t$ 不为空,说明当前行是有效行,我们将其加入答案数组中,并且清空 $t$。继续遍历下一行。
118118

119119
时间复杂度 $O(L)$,空间复杂度 $O(L)$,其中 $L$ 是源代码的总长度。
120120

‎solution/0700-0799/0722.Remove Comments/README_EN.md

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,20 +58,20 @@ tags:
5858
<strong>Explanation:</strong> The line by line code is visualized as below:
5959
/*Test program */
6060
int main()
61-
{
62-
// variable declaration
61+
{
62+
// variable declaration
6363
int a, b, c;
6464
/* This is a test
65-
multiline
66-
comment for
65+
multiline
66+
comment for
6767
testing */
6868
a = b + c;
6969
}
7070
The string /* denotes a block comment, including line 1 and lines 6-9. The string // denotes line 4 as comments.
7171
The line by line output code is visualized as below:
7272
int main()
73-
{
74-
73+
{
74+
7575
int a, b, c;
7676
a = b + c;
7777
}
@@ -102,7 +102,19 @@ a = b + c;
102102

103103
<!-- solution:start -->
104104

105-
### Solution 1
105+
### Solution 1: Case Analysis
106+
107+
We use a variable $\textit{blockComment}$ to indicate whether we are currently in a block comment. Initially, $\textit{blockComment}$ is `false`. We use a variable $t$ to store the valid characters of the current line.
108+
109+
Next, we traverse each line and discuss the following cases:
110+
111+
If we are currently in a block comment, and the current character and the next character are `'*/'`, it means the block comment ends. We set $\textit{blockComment}$ to `false` and skip these two characters. Otherwise, we continue in the block comment state without doing anything.
112+
113+
If we are not currently in a block comment, and the current character and the next character are `'/*'`, it means a block comment starts. We set $\textit{blockComment}$ to `true` and skip these two characters. If the current character and the next character are `'//'`, it means a line comment starts, and we exit the current line traversal. Otherwise, the current character is a valid character, and we add it to $t$.
114+
115+
After traversing the current line, if $\textit{blockComment}$ is `false` and $t$ is not empty, it means the current line is valid. We add it to the answer array and clear $t$. Continue to traverse the next line.
116+
117+
The time complexity is $O(L)$, and the space complexity is $O(L)$, where $L$ is the total length of the source code.
106118

107119
<!-- tabs:start -->
108120

‎solution/0700-0799/0727.Minimum Window Subsequence/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ s1 = "abcdebdde", s2 = "bde"
6060

6161
### 方法一:动态规划
6262

63-
我们定义 $f[i][j]$ 表示字符串 $s1$ 的前 $i$ 个字符包含字符串 $s2$ 的前 $j$ 个字符时的最短子串的起始位置,如果不存在则为 $0$。
63+
我们定义 $f[i][j]$ 表示字符串 $\textit{s1}$ 的前 $i$ 个字符包含字符串 $\textit{s2}$ 的前 $j$ 个字符时的最短子串的起始位置,如果不存在则为 $0$。
6464

6565
我们可以得到状态转移方程:
6666

@@ -72,9 +72,9 @@ f[i - 1][j], & s1[i-1] \ne s2[j-1]
7272
\end{cases}
7373
$$
7474

75-
接下来我们只需要遍历 $s1$,如果 $f[i][n] \gt 0$,则更新最短子串的起始位置和长度。最后返回最短子串即可。
75+
接下来我们只需要遍历 $\textit{s1}$,如果 $f[i][n] \gt 0$,则更新最短子串的起始位置和长度。最后返回最短子串即可。
7676

77-
时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别为字符串 $s1$ 和 $s2$ 的长度。
77+
时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别为字符串 $\textit{s1}$ 和 $\textit{s2}$ 的长度。
7878

7979
<!-- tabs:start -->
8080

‎solution/0700-0799/0727.Minimum Window Subsequence/README_EN.md

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ tags:
2828
<pre>
2929
<strong>Input:</strong> s1 = &quot;abcdebdde&quot;, s2 = &quot;bde&quot;
3030
<strong>Output:</strong> &quot;bcde&quot;
31-
<strong>Explanation:</strong>
31+
<strong>Explanation:</strong>
3232
&quot;bcde&quot; is the answer because it occurs before &quot;bdde&quot; which has the same length.
3333
&quot;deb&quot; is not a smaller window because the elements of s2 in the window must occur in order.
3434
</pre>
@@ -55,7 +55,23 @@ tags:
5555

5656
<!-- solution:start -->
5757

58-
### Solution 1
58+
### Solution 1: Dynamic Programming
59+
60+
We define $f[i][j]$ to represent the starting position of the shortest substring of the first $i$ characters of string $\textit{s1}$ that contains the first $j$ characters of string $\textit{s2}$. If it does not exist, it is $0$.
61+
62+
We can derive the state transition equation:
63+
64+
$$
65+
f[i][j] = \begin{cases}
66+
i, & j = 1 \textit{ and } s1[i-1] = s2[j] \\
67+
f[i - 1][j - 1], & j > 1 \textit{ and } s1[i-1] = s2[j-1] \\
68+
f[i - 1][j], & s1[i-1] \ne s2[j-1]
69+
\end{cases}
70+
$$
71+
72+
Next, we only need to traverse $\textit{s1}$. If $f[i][n] \gt 0$, update the starting position and length of the shortest substring. Finally, return the shortest substring.
73+
74+
The time complexity is $O(m \times n)$, and the space complexity is $O(m \times n)$. Here, $m$ and $n$ are the lengths of strings $\textit{s1}$ and $\textit{s2}$, respectively.
5975

6076
<!-- tabs:start -->
6177

‎solution/0700-0799/0733.Flood Fill/README.md

Lines changed: 174 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,11 @@ tags:
7575

7676
<!-- solution:start -->
7777

78-
### 方法一:Flood fill 算法
78+
### 方法一:DFS
7979

80-
Flood fill 算法是从一个区域中提取若干个连通的点与其他相邻区域区分开(或分别染成不同颜色)的经典算法。因为其思路类似洪水从一个区域扩散到所有能到达的区域而得名
80+
我们记初始像素的颜色为 $\textit{oc}$,如果 $\textit{oc}$ 不等于目标颜色 $\textit{color}$,我们就从 $(\textit{sr}, \textit{sc})$ 开始深度优先搜索,将所有符合条件的像素点的颜色都更改成目标颜色
8181

82-
最简单的实现方法是采用 DFS 的递归方法,也可以采用 BFS 的迭代来实现。
83-
84-
时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别为图像的行数和列数。
82+
时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别为二维数组 $\textit{image}$ 的行数和列数。
8583

8684
<!-- tabs:start -->
8785

@@ -92,50 +90,47 @@ class Solution:
9290
def floodFill(
9391
self, image: List[List[int]], sr: int, sc: int, color: int
9492
) -> List[List[int]]:
95-
def dfs(i, j):
96-
if (
97-
not 0 <= i < m
98-
or not 0 <= j < n
99-
or image[i][j] != oc
100-
or image[i][j] == color
101-
):
102-
return
93+
def dfs(i: int, j: int):
10394
image[i][j] = color
10495
for a, b in pairwise(dirs):
105-
dfs(i + a, j + b)
96+
x, y = i + a, j + b
97+
if 0 <= x < len(image) and 0 <= y < len(image[0]) and image[x][y] == oc:
98+
dfs(x, y)
10699

107-
dirs = (-1, 0, 1, 0, -1)
108-
m, n = len(image), len(image[0])
109100
oc = image[sr][sc]
110-
dfs(sr, sc)
101+
if oc != color:
102+
dirs = (-1, 0, 1, 0, -1)
103+
dfs(sr, sc)
111104
return image
112105
```
113106

114107
#### Java
115108

116109
```java
117110
class Solution {
118-
private int[] dirs = {-1, 0, 1, 0, -1};
119111
private int[][] image;
120-
private int nc;
121112
private int oc;
113+
private int color;
114+
private final int[] dirs = {-1, 0, 1, 0, -1};
122115

123116
public int[][] floodFill(int[][] image, int sr, int sc, int color) {
124-
nc = color;
125117
oc = image[sr][sc];
118+
if (oc == color) {
119+
return image;
120+
}
126121
this.image = image;
122+
this.color = color;
127123
dfs(sr, sc);
128124
return image;
129125
}
130126

131127
private void dfs(int i, int j) {
132-
if (i < 0 || i >= image.length || j < 0 || j >= image[0].length || image[i][j] != oc
133-
|| image[i][j] == nc) {
134-
return;
135-
}
136-
image[i][j] = nc;
128+
image[i][j] = color;
137129
for (int k = 0; k < 4; ++k) {
138-
dfs(i + dirs[k], j + dirs[k + 1]);
130+
int x = i + dirs[k], y = j + dirs[k + 1];
131+
if (x >= 0 && x < image.length && y >= 0 && y < image[0].length && image[x][y] == oc) {
132+
dfs(x, y);
133+
}
139134
}
140135
}
141136
}
@@ -149,14 +144,17 @@ public:
149144
vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) {
150145
int m = image.size(), n = image[0].size();
151146
int oc = image[sr][sc];
152-
int dirs[5] = {-1, 0, 1, 0, -1};
153-
function<void(int, int)> dfs = [&](int i, int j) {
154-
if (i < 0 || i >= m || j < 0 || j >= n || image[i][j] != oc || image[i][j] == color) {
155-
return;
156-
}
147+
if (oc == color) {
148+
return image;
149+
}
150+
const int dirs[5] = {-1, 0, 1, 0, -1};
151+
auto dfs = [&](this auto&& dfs, int i, int j) -> void {
157152
image[i][j] = color;
158153
for (int k = 0; k < 4; ++k) {
159-
dfs(i + dirs[k], j + dirs[k + 1]);
154+
int x = i + dirs[k], y = j + dirs[k + 1];
155+
if (x >= 0 && x < m && y >= 0 && y < n && image[x][y] == oc) {
156+
dfs(x, y);
157+
}
160158
}
161159
};
162160
dfs(sr, sc);
@@ -169,19 +167,25 @@ public:
169167
170168
```go
171169
func floodFill(image [][]int, sr int, sc int, color int) [][]int {
172-
oc := image[sr][sc]
173170
m, n := len(image), len(image[0])
171+
oc := image[sr][sc]
172+
if oc == color {
173+
return image
174+
}
175+
174176
dirs := []int{-1, 0, 1, 0, -1}
177+
175178
var dfs func(i, j int)
176179
dfs = func(i, j int) {
177-
if i < 0 || i >= m || j < 0 || j >= n || image[i][j] != oc || image[i][j] == color {
178-
return
179-
}
180180
image[i][j] = color
181181
for k := 0; k < 4; k++ {
182-
dfs(i+dirs[k], j+dirs[k+1])
182+
x, y := i+dirs[k], j+dirs[k+1]
183+
if x >= 0 && x < m && y >= 0 && y < n && image[x][y] == oc {
184+
dfs(x, y)
185+
}
183186
}
184187
}
188+
185189
dfs(sr, sc)
186190
return image
187191
}
@@ -190,27 +194,25 @@ func floodFill(image [][]int, sr int, sc int, color int) [][]int {
190194
#### TypeScript
191195

192196
```ts
193-
function floodFill(image: number[][], sr: number, sc: number, newColor: number): number[][] {
194-
const m = image.length;
195-
const n = image[0].length;
196-
const target = image[sr][sc];
197-
const dfs = (i: number, j: number) => {
198-
if (
199-
i < 0 ||
200-
i === m ||
201-
j < 0 ||
202-
j === n ||
203-
image[i][j] !== target ||
204-
image[i][j] === newColor
205-
) {
206-
return;
197+
function floodFill(image: number[][], sr: number, sc: number, color: number): number[][] {
198+
const [m, n] = [image.length, image[0].length];
199+
const oc = image[sr][sc];
200+
if (oc === color) {
201+
return image;
202+
}
203+
204+
const dirs = [-1, 0, 1, 0, -1];
205+
206+
const dfs = (i: number, j: number): void => {
207+
image[i][j] = color;
208+
for (let k = 0; k < 4; k++) {
209+
const [x, y] = [i + dirs[k], j + dirs[k + 1]];
210+
if (x >= 0 && x < m && y >= 0 && y < n && image[x][y] === oc) {
211+
dfs(x, y);
212+
}
207213
}
208-
image[i][j] = newColor;
209-
dfs(i + 1, j);
210-
dfs(i - 1, j);
211-
dfs(i, j + 1);
212-
dfs(i, j - 1);
213214
};
215+
214216
dfs(sr, sc);
215217
return image;
216218
}
@@ -220,26 +222,42 @@ function floodFill(image: number[][], sr: number, sc: number, newColor: number):
220222

221223
```rust
222224
impl Solution {
223-
fn dfs(image: &mut Vec<Vec<i32>>, sr: i32, sc: i32, new_color: i32, target: i32) {
224-
if sr < 0 || sr == (image.len() as i32) || sc < 0 || sc == (image[0].len() as i32) {
225-
return;
226-
}
225+
pub fn flood_fill(mut image: Vec<Vec<i32>>, sr: i32, sc: i32, color: i32) -> Vec<Vec<i32>> {
226+
let m = image.len();
227+
let n = image[0].len();
227228
let sr = sr as usize;
228229
let sc = sc as usize;
229-
if sr < 0 || image[sr][sc] == new_color || image[sr][sc] != target {
230-
return;
230+
231+
let oc = image[sr][sc];
232+
if oc == color {
233+
return image;
231234
}
232-
image[sr][sc] = new_color;
233-
let sr = sr as i32;
234-
let sc = sc as i32;
235-
Self::dfs(image, sr + 1, sc, new_color, target);
236-
Self::dfs(image, sr - 1, sc, new_color, target);
237-
Self::dfs(image, sr, sc + 1, new_color, target);
238-
Self::dfs(image, sr, sc - 1, new_color, target);
239-
}
240-
pub fn flood_fill(image: Vec<Vec<i32>>, sr: i32, sc: i32, new_color: i32) -> Vec<Vec<i32>> {
241-
let target = image[sr as usize][sc as usize];
242-
Self::dfs(&mut image, sr, sc, new_color, target);
235+
let dirs = [-1, 0, 1, 0, -1];
236+
fn dfs(
237+
image: &mut Vec<Vec<i32>>,
238+
i: usize,
239+
j: usize,
240+
oc: i32,
241+
color: i32,
242+
m: usize,
243+
n: usize,
244+
dirs: &[i32; 5],
245+
) {
246+
image[i][j] = color;
247+
for k in 0..4 {
248+
let x = i as isize + dirs[k] as isize;
249+
let y = j as isize + dirs[k + 1] as isize;
250+
if x >= 0 && x < m as isize && y >= 0 && y < n as isize {
251+
let x = x as usize;
252+
let y = y as usize;
253+
if image[x][y] == oc {
254+
dfs(image, x, y, oc, color, m, n, dirs);
255+
}
256+
}
257+
}
258+
}
259+
260+
dfs(&mut image, sr, sc, oc, color, m, n, &dirs);
243261
image
244262
}
245263
}
@@ -251,7 +269,13 @@ impl Solution {
251269

252270
<!-- solution:start -->
253271

254-
### 方法二
272+
### 方法二:BFS
273+
274+
我们首先判断初始像素的颜色是否等于目标颜色,如果等于,直接返回原图像。否则,我们可以使用广度优先搜索的方法,从 $(\textit{sr}, \textit{sc})$ 开始,将所有符合条件的像素点的颜色都更改成目标颜色。
275+
276+
具体地,我们定义一个队列 $\textit{q}$,将初始像素 $(\textit{sr}, \textit{sc})$ 加入队列。然后我们不断从队列中取出像素点 $(i, j)$,将其颜色更改成目标颜色,并将其上下左右四个方向上与初始像素的原始颜色相同的像素点加入队列。直到队列为空,我们就完成了图像的渲染。
277+
278+
时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别为二维数组 $\textit{image}$ 的行数和列数。
255279

256280
<!-- tabs:start -->
257281

@@ -363,6 +387,82 @@ func floodFill(image [][]int, sr int, sc int, color int) [][]int {
363387
}
364388
```
365389

390+
#### TypeScript
391+
392+
```ts
393+
function floodFill(image: number[][], sr: number, sc: number, color: number): number[][] {
394+
if (image[sr][sc] === color) {
395+
return image;
396+
}
397+
398+
const oc = image[sr][sc];
399+
image[sr][sc] = color;
400+
401+
const q: [number, number][] = [];
402+
q.push([sr, sc]);
403+
404+
const dirs = [-1, 0, 1, 0, -1];
405+
const [m, n] = [image.length, image[0].length];
406+
407+
while (q.length > 0) {
408+
const [a, b] = q.shift()!;
409+
for (let k = 0; k < 4; ++k) {
410+
const x = a + dirs[k];
411+
const y = b + dirs[k + 1];
412+
if (x >= 0 && x < m && y >= 0 && y < n && image[x][y] === oc) {
413+
q.push([x, y]);
414+
image[x][y] = color;
415+
}
416+
}
417+
}
418+
419+
return image;
420+
}
421+
```
422+
423+
#### Rust
424+
425+
```rust
426+
use std::collections::VecDeque;
427+
428+
impl Solution {
429+
pub fn flood_fill(mut image: Vec<Vec<i32>>, sr: i32, sc: i32, color: i32) -> Vec<Vec<i32>> {
430+
let m = image.len();
431+
let n = image[0].len();
432+
let (sr, sc) = (sr as usize, sc as usize);
433+
434+
if image[sr][sc] == color {
435+
return image;
436+
}
437+
438+
let oc = image[sr][sc];
439+
image[sr][sc] = color;
440+
441+
let mut q = VecDeque::new();
442+
q.push_back((sr, sc));
443+
444+
let dirs = [-1, 0, 1, 0, -1];
445+
446+
while let Some((i, j)) = q.pop_front() {
447+
for k in 0..4 {
448+
let x = i as isize + dirs[k] as isize;
449+
let y = j as isize + dirs[k + 1] as isize;
450+
451+
if x >= 0 && x < m as isize && y >= 0 && y < n as isize {
452+
let (x, y) = (x as usize, y as usize);
453+
if image[x][y] == oc {
454+
q.push_back((x, y));
455+
image[x][y] = color;
456+
}
457+
}
458+
}
459+
}
460+
461+
image
462+
}
463+
}
464+
```
465+
366466
<!-- tabs:end -->
367467

368468
<!-- solution:end -->

‎solution/0700-0799/0733.Flood Fill/README_EN.md

Lines changed: 176 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,11 @@ tags:
7979

8080
<!-- solution:start -->
8181

82-
### Solution 1
82+
### Solution 1: DFS
83+
84+
We denote the initial pixel's color as $\textit{oc}$. If $\textit{oc}$ is not equal to the target color $\textit{color}$, we start a depth-first search from $(\textit{sr}, \textit{sc})$ to change the color of all eligible pixels to the target color.
85+
86+
The time complexity is $O(m \times n)$, and the space complexity is $O(m \times n)$. Here, $m$ and $n$ are the number of rows and columns of the 2D array $\textit{image}$, respectively.
8387

8488
<!-- tabs:start -->
8589

@@ -90,50 +94,47 @@ class Solution:
9094
def floodFill(
9195
self, image: List[List[int]], sr: int, sc: int, color: int
9296
) -> List[List[int]]:
93-
def dfs(i, j):
94-
if (
95-
not 0 <= i < m
96-
or not 0 <= j < n
97-
or image[i][j] != oc
98-
or image[i][j] == color
99-
):
100-
return
97+
def dfs(i: int, j: int):
10198
image[i][j] = color
10299
for a, b in pairwise(dirs):
103-
dfs(i + a, j + b)
100+
x, y = i + a, j + b
101+
if 0 <= x < len(image) and 0 <= y < len(image[0]) and image[x][y] == oc:
102+
dfs(x, y)
104103

105-
dirs = (-1, 0, 1, 0, -1)
106-
m, n = len(image), len(image[0])
107104
oc = image[sr][sc]
108-
dfs(sr, sc)
105+
if oc != color:
106+
dirs = (-1, 0, 1, 0, -1)
107+
dfs(sr, sc)
109108
return image
110109
```
111110

112111
#### Java
113112

114113
```java
115114
class Solution {
116-
private int[] dirs = {-1, 0, 1, 0, -1};
117115
private int[][] image;
118-
private int nc;
119116
private int oc;
117+
private int color;
118+
private final int[] dirs = {-1, 0, 1, 0, -1};
120119

121120
public int[][] floodFill(int[][] image, int sr, int sc, int color) {
122-
nc = color;
123121
oc = image[sr][sc];
122+
if (oc == color) {
123+
return image;
124+
}
124125
this.image = image;
126+
this.color = color;
125127
dfs(sr, sc);
126128
return image;
127129
}
128130

129131
private void dfs(int i, int j) {
130-
if (i < 0 || i >= image.length || j < 0 || j >= image[0].length || image[i][j] != oc
131-
|| image[i][j] == nc) {
132-
return;
133-
}
134-
image[i][j] = nc;
132+
image[i][j] = color;
135133
for (int k = 0; k < 4; ++k) {
136-
dfs(i + dirs[k], j + dirs[k + 1]);
134+
int x = i + dirs[k], y = j + dirs[k + 1];
135+
if (x >= 0 && x < image.length && y >= 0 && y < image[0].length && image[x][y] == oc) {
136+
dfs(x, y);
137+
}
137138
}
138139
}
139140
}
@@ -147,14 +148,17 @@ public:
147148
vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) {
148149
int m = image.size(), n = image[0].size();
149150
int oc = image[sr][sc];
150-
int dirs[5] = {-1, 0, 1, 0, -1};
151-
function<void(int, int)> dfs = [&](int i, int j) {
152-
if (i < 0 || i >= m || j < 0 || j >= n || image[i][j] != oc || image[i][j] == color) {
153-
return;
154-
}
151+
if (oc == color) {
152+
return image;
153+
}
154+
const int dirs[5] = {-1, 0, 1, 0, -1};
155+
auto dfs = [&](this auto&& dfs, int i, int j) -> void {
155156
image[i][j] = color;
156157
for (int k = 0; k < 4; ++k) {
157-
dfs(i + dirs[k], j + dirs[k + 1]);
158+
int x = i + dirs[k], y = j + dirs[k + 1];
159+
if (x >= 0 && x < m && y >= 0 && y < n && image[x][y] == oc) {
160+
dfs(x, y);
161+
}
158162
}
159163
};
160164
dfs(sr, sc);
@@ -167,19 +171,25 @@ public:
167171
168172
```go
169173
func floodFill(image [][]int, sr int, sc int, color int) [][]int {
170-
oc := image[sr][sc]
171174
m, n := len(image), len(image[0])
175+
oc := image[sr][sc]
176+
if oc == color {
177+
return image
178+
}
179+
172180
dirs := []int{-1, 0, 1, 0, -1}
181+
173182
var dfs func(i, j int)
174183
dfs = func(i, j int) {
175-
if i < 0 || i >= m || j < 0 || j >= n || image[i][j] != oc || image[i][j] == color {
176-
return
177-
}
178184
image[i][j] = color
179185
for k := 0; k < 4; k++ {
180-
dfs(i+dirs[k], j+dirs[k+1])
186+
x, y := i+dirs[k], j+dirs[k+1]
187+
if x >= 0 && x < m && y >= 0 && y < n && image[x][y] == oc {
188+
dfs(x, y)
189+
}
181190
}
182191
}
192+
183193
dfs(sr, sc)
184194
return image
185195
}
@@ -188,27 +198,25 @@ func floodFill(image [][]int, sr int, sc int, color int) [][]int {
188198
#### TypeScript
189199

190200
```ts
191-
function floodFill(image: number[][], sr: number, sc: number, newColor: number): number[][] {
192-
const m = image.length;
193-
const n = image[0].length;
194-
const target = image[sr][sc];
195-
const dfs = (i: number, j: number) => {
196-
if (
197-
i < 0 ||
198-
i === m ||
199-
j < 0 ||
200-
j === n ||
201-
image[i][j] !== target ||
202-
image[i][j] === newColor
203-
) {
204-
return;
201+
function floodFill(image: number[][], sr: number, sc: number, color: number): number[][] {
202+
const [m, n] = [image.length, image[0].length];
203+
const oc = image[sr][sc];
204+
if (oc === color) {
205+
return image;
206+
}
207+
208+
const dirs = [-1, 0, 1, 0, -1];
209+
210+
const dfs = (i: number, j: number): void => {
211+
image[i][j] = color;
212+
for (let k = 0; k < 4; k++) {
213+
const [x, y] = [i + dirs[k], j + dirs[k + 1]];
214+
if (x >= 0 && x < m && y >= 0 && y < n && image[x][y] === oc) {
215+
dfs(x, y);
216+
}
205217
}
206-
image[i][j] = newColor;
207-
dfs(i + 1, j);
208-
dfs(i - 1, j);
209-
dfs(i, j + 1);
210-
dfs(i, j - 1);
211218
};
219+
212220
dfs(sr, sc);
213221
return image;
214222
}
@@ -218,26 +226,42 @@ function floodFill(image: number[][], sr: number, sc: number, newColor: number):
218226

219227
```rust
220228
impl Solution {
221-
fn dfs(image: &mut Vec<Vec<i32>>, sr: i32, sc: i32, new_color: i32, target: i32) {
222-
if sr < 0 || sr == (image.len() as i32) || sc < 0 || sc == (image[0].len() as i32) {
223-
return;
224-
}
229+
pub fn flood_fill(mut image: Vec<Vec<i32>>, sr: i32, sc: i32, color: i32) -> Vec<Vec<i32>> {
230+
let m = image.len();
231+
let n = image[0].len();
225232
let sr = sr as usize;
226233
let sc = sc as usize;
227-
if sr < 0 || image[sr][sc] == new_color || image[sr][sc] != target {
228-
return;
234+
235+
let oc = image[sr][sc];
236+
if oc == color {
237+
return image;
229238
}
230-
image[sr][sc] = new_color;
231-
let sr = sr as i32;
232-
let sc = sc as i32;
233-
Self::dfs(image, sr + 1, sc, new_color, target);
234-
Self::dfs(image, sr - 1, sc, new_color, target);
235-
Self::dfs(image, sr, sc + 1, new_color, target);
236-
Self::dfs(image, sr, sc - 1, new_color, target);
237-
}
238-
pub fn flood_fill(image: Vec<Vec<i32>>, sr: i32, sc: i32, new_color: i32) -> Vec<Vec<i32>> {
239-
let target = image[sr as usize][sc as usize];
240-
Self::dfs(&mut image, sr, sc, new_color, target);
239+
let dirs = [-1, 0, 1, 0, -1];
240+
fn dfs(
241+
image: &mut Vec<Vec<i32>>,
242+
i: usize,
243+
j: usize,
244+
oc: i32,
245+
color: i32,
246+
m: usize,
247+
n: usize,
248+
dirs: &[i32; 5],
249+
) {
250+
image[i][j] = color;
251+
for k in 0..4 {
252+
let x = i as isize + dirs[k] as isize;
253+
let y = j as isize + dirs[k + 1] as isize;
254+
if x >= 0 && x < m as isize && y >= 0 && y < n as isize {
255+
let x = x as usize;
256+
let y = y as usize;
257+
if image[x][y] == oc {
258+
dfs(image, x, y, oc, color, m, n, dirs);
259+
}
260+
}
261+
}
262+
}
263+
264+
dfs(&mut image, sr, sc, oc, color, m, n, &dirs);
241265
image
242266
}
243267
}
@@ -249,7 +273,13 @@ impl Solution {
249273

250274
<!-- solution:start -->
251275

252-
### Solution 2
276+
### Solution 2: BFS
277+
278+
We first check if the initial pixel's color is equal to the target color. If it is, we return the original image directly. Otherwise, we can use the breadth-first search method, starting from $(\textit{sr}, \textit{sc})$, to change the color of all eligible pixels to the target color.
279+
280+
Specifically, we define a queue $\textit{q}$ and add the initial pixel $(\textit{sr}, \textit{sc})$ to the queue. Then, we continuously take pixels $(i, j)$ from the queue, change their color to the target color, and add the pixels in the four directions (up, down, left, right) that have the same original color as the initial pixel to the queue. When the queue is empty, we have completed the flood fill.
281+
282+
The time complexity is $O(m \times n)$, and the space complexity is $O(m \times n)$. Here, $m$ and $n$ are the number of rows and columns of the 2D array $\textit{image}$, respectively.
253283

254284
<!-- tabs:start -->
255285

@@ -361,6 +391,82 @@ func floodFill(image [][]int, sr int, sc int, color int) [][]int {
361391
}
362392
```
363393

394+
#### TypeScript
395+
396+
```ts
397+
function floodFill(image: number[][], sr: number, sc: number, color: number): number[][] {
398+
if (image[sr][sc] === color) {
399+
return image;
400+
}
401+
402+
const oc = image[sr][sc];
403+
image[sr][sc] = color;
404+
405+
const q: [number, number][] = [];
406+
q.push([sr, sc]);
407+
408+
const dirs = [-1, 0, 1, 0, -1];
409+
const [m, n] = [image.length, image[0].length];
410+
411+
while (q.length > 0) {
412+
const [a, b] = q.shift()!;
413+
for (let k = 0; k < 4; ++k) {
414+
const x = a + dirs[k];
415+
const y = b + dirs[k + 1];
416+
if (x >= 0 && x < m && y >= 0 && y < n && image[x][y] === oc) {
417+
q.push([x, y]);
418+
image[x][y] = color;
419+
}
420+
}
421+
}
422+
423+
return image;
424+
}
425+
```
426+
427+
#### Rust
428+
429+
```rust
430+
use std::collections::VecDeque;
431+
432+
impl Solution {
433+
pub fn flood_fill(mut image: Vec<Vec<i32>>, sr: i32, sc: i32, color: i32) -> Vec<Vec<i32>> {
434+
let m = image.len();
435+
let n = image[0].len();
436+
let (sr, sc) = (sr as usize, sc as usize);
437+
438+
if image[sr][sc] == color {
439+
return image;
440+
}
441+
442+
let oc = image[sr][sc];
443+
image[sr][sc] = color;
444+
445+
let mut q = VecDeque::new();
446+
q.push_back((sr, sc));
447+
448+
let dirs = [-1, 0, 1, 0, -1];
449+
450+
while let Some((i, j)) = q.pop_front() {
451+
for k in 0..4 {
452+
let x = i as isize + dirs[k] as isize;
453+
let y = j as isize + dirs[k + 1] as isize;
454+
455+
if x >= 0 && x < m as isize && y >= 0 && y < n as isize {
456+
let (x, y) = (x as usize, y as usize);
457+
if image[x][y] == oc {
458+
q.push_back((x, y));
459+
image[x][y] = color;
460+
}
461+
}
462+
}
463+
}
464+
465+
image
466+
}
467+
}
468+
```
469+
364470
<!-- tabs:end -->
365471

366472
<!-- solution:end -->

‎solution/0700-0799/0733.Flood Fill/Solution.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,20 @@ class Solution {
33
vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) {
44
int m = image.size(), n = image[0].size();
55
int oc = image[sr][sc];
6-
int dirs[5] = {-1, 0, 1, 0, -1};
7-
function<void(int, int)> dfs = [&](int i, int j) {
8-
if (i < 0 || i >= m || j < 0 || j >= n || image[i][j] != oc || image[i][j] == color) {
9-
return;
10-
}
6+
if (oc == color) {
7+
return image;
8+
}
9+
const int dirs[5] = {-1, 0, 1, 0, -1};
10+
auto dfs = [&](this auto&& dfs, int i, int j) -> void {
1111
image[i][j] = color;
1212
for (int k = 0; k < 4; ++k) {
13-
dfs(i + dirs[k], j + dirs[k + 1]);
13+
int x = i + dirs[k], y = j + dirs[k + 1];
14+
if (x >= 0 && x < m && y >= 0 && y < n && image[x][y] == oc) {
15+
dfs(x, y);
16+
}
1417
}
1518
};
1619
dfs(sr, sc);
1720
return image;
1821
}
19-
};
22+
};
Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
11
func floodFill(image [][]int, sr int, sc int, color int) [][]int {
2-
oc := image[sr][sc]
32
m, n := len(image), len(image[0])
3+
oc := image[sr][sc]
4+
if oc == color {
5+
return image
6+
}
7+
48
dirs := []int{-1, 0, 1, 0, -1}
9+
510
var dfs func(i, j int)
611
dfs = func(i, j int) {
7-
if i < 0 || i >= m || j < 0 || j >= n || image[i][j] != oc || image[i][j] == color {
8-
return
9-
}
1012
image[i][j] = color
1113
for k := 0; k < 4; k++ {
12-
dfs(i+dirs[k], j+dirs[k+1])
14+
x, y := i+dirs[k], j+dirs[k+1]
15+
if x >= 0 && x < m && y >= 0 && y < n && image[x][y] == oc {
16+
dfs(x, y)
17+
}
1318
}
1419
}
20+
1521
dfs(sr, sc)
1622
return image
17-
}
23+
}
Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,27 @@
11
class Solution {
2-
private int[] dirs = {-1, 0, 1, 0, -1};
32
private int[][] image;
4-
private int nc;
53
private int oc;
4+
private int color;
5+
private final int[] dirs = {-1, 0, 1, 0, -1};
66

77
public int[][] floodFill(int[][] image, int sr, int sc, int color) {
8-
nc = color;
98
oc = image[sr][sc];
9+
if (oc == color) {
10+
return image;
11+
}
1012
this.image = image;
13+
this.color = color;
1114
dfs(sr, sc);
1215
return image;
1316
}
1417

1518
private void dfs(int i, int j) {
16-
if (i < 0 || i >= image.length || j < 0 || j >= image[0].length || image[i][j] != oc
17-
|| image[i][j] == nc) {
18-
return;
19-
}
20-
image[i][j] = nc;
19+
image[i][j] = color;
2120
for (int k = 0; k < 4; ++k) {
22-
dfs(i + dirs[k], j + dirs[k + 1]);
21+
int x = i + dirs[k], y = j + dirs[k + 1];
22+
if (x >= 0 && x < image.length && y >= 0 && y < image[0].length && image[x][y] == oc) {
23+
dfs(x, y);
24+
}
2325
}
2426
}
25-
}
27+
}

‎solution/0700-0799/0733.Flood Fill/Solution.py

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,15 @@ class Solution:
22
def floodFill(
33
self, image: List[List[int]], sr: int, sc: int, color: int
44
) -> List[List[int]]:
5-
def dfs(i, j):
6-
if (
7-
not 0 <= i < m
8-
or not 0 <= j < n
9-
or image[i][j] != oc
10-
or image[i][j] == color
11-
):
12-
return
5+
def dfs(i: int, j: int):
136
image[i][j] = color
147
for a, b in pairwise(dirs):
15-
dfs(i + a, j + b)
8+
x, y = i + a, j + b
9+
if 0 <= x < len(image) and 0 <= y < len(image[0]) and image[x][y] == oc:
10+
dfs(x, y)
1611

17-
dirs = (-1, 0, 1, 0, -1)
18-
m, n = len(image), len(image[0])
1912
oc = image[sr][sc]
20-
dfs(sr, sc)
13+
if oc != color:
14+
dirs = (-1, 0, 1, 0, -1)
15+
dfs(sr, sc)
2116
return image
Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,40 @@
11
impl Solution {
2-
fn dfs(image: &mut Vec<Vec<i32>>, sr: i32, sc: i32, new_color: i32, target: i32) {
3-
if sr < 0 || sr == (image.len() as i32) || sc < 0 || sc == (image[0].len() as i32) {
4-
return;
5-
}
2+
pub fn flood_fill(mut image: Vec<Vec<i32>>, sr: i32, sc: i32, color: i32) -> Vec<Vec<i32>> {
3+
let m = image.len();
4+
let n = image[0].len();
65
let sr = sr as usize;
76
let sc = sc as usize;
8-
if sr < 0 || image[sr][sc] == new_color || image[sr][sc] != target {
9-
return;
7+
8+
let oc = image[sr][sc];
9+
if oc == color {
10+
return image;
1011
}
11-
image[sr][sc] = new_color;
12-
let sr = sr as i32;
13-
let sc = sc as i32;
14-
Self::dfs(image, sr + 1, sc, new_color, target);
15-
Self::dfs(image, sr - 1, sc, new_color, target);
16-
Self::dfs(image, sr, sc + 1, new_color, target);
17-
Self::dfs(image, sr, sc - 1, new_color, target);
18-
}
19-
pub fn flood_fill(image: Vec<Vec<i32>>, sr: i32, sc: i32, new_color: i32) -> Vec<Vec<i32>> {
20-
let target = image[sr as usize][sc as usize];
21-
Self::dfs(&mut image, sr, sc, new_color, target);
12+
let dirs = [-1, 0, 1, 0, -1];
13+
fn dfs(
14+
image: &mut Vec<Vec<i32>>,
15+
i: usize,
16+
j: usize,
17+
oc: i32,
18+
color: i32,
19+
m: usize,
20+
n: usize,
21+
dirs: &[i32; 5],
22+
) {
23+
image[i][j] = color;
24+
for k in 0..4 {
25+
let x = i as isize + dirs[k] as isize;
26+
let y = j as isize + dirs[k + 1] as isize;
27+
if x >= 0 && x < m as isize && y >= 0 && y < n as isize {
28+
let x = x as usize;
29+
let y = y as usize;
30+
if image[x][y] == oc {
31+
dfs(image, x, y, oc, color, m, n, dirs);
32+
}
33+
}
34+
}
35+
}
36+
37+
dfs(&mut image, sr, sc, oc, color, m, n, &dirs);
2238
image
2339
}
2440
}
Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,22 @@
1-
function floodFill(image: number[][], sr: number, sc: number, newColor: number): number[][] {
2-
const m = image.length;
3-
const n = image[0].length;
4-
const target = image[sr][sc];
5-
const dfs = (i: number, j: number) => {
6-
if (
7-
i < 0 ||
8-
i === m ||
9-
j < 0 ||
10-
j === n ||
11-
image[i][j] !== target ||
12-
image[i][j] === newColor
13-
) {
14-
return;
1+
function floodFill(image: number[][], sr: number, sc: number, color: number): number[][] {
2+
const [m, n] = [image.length, image[0].length];
3+
const oc = image[sr][sc];
4+
if (oc === color) {
5+
return image;
6+
}
7+
8+
const dirs = [-1, 0, 1, 0, -1];
9+
10+
const dfs = (i: number, j: number): void => {
11+
image[i][j] = color;
12+
for (let k = 0; k < 4; k++) {
13+
const [x, y] = [i + dirs[k], j + dirs[k + 1]];
14+
if (x >= 0 && x < m && y >= 0 && y < n && image[x][y] === oc) {
15+
dfs(x, y);
16+
}
1517
}
16-
image[i][j] = newColor;
17-
dfs(i + 1, j);
18-
dfs(i - 1, j);
19-
dfs(i, j + 1);
20-
dfs(i, j - 1);
2118
};
19+
2220
dfs(sr, sc);
2321
return image;
2422
}

‎solution/0700-0799/0733.Flood Fill/Solution2.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
class Solution {
22
public:
33
vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) {
4-
if (image[sr][sc] == color) return image;
4+
if (image[sr][sc] == color) {
5+
return image;
6+
}
57
int oc = image[sr][sc];
68
image[sr][sc] = color;
79
queue<pair<int, int>> q;
@@ -21,4 +23,4 @@ class Solution {
2123
}
2224
return image;
2325
}
24-
};
26+
};
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
use std::collections::VecDeque;
2+
3+
impl Solution {
4+
pub fn flood_fill(mut image: Vec<Vec<i32>>, sr: i32, sc: i32, color: i32) -> Vec<Vec<i32>> {
5+
let m = image.len();
6+
let n = image[0].len();
7+
let (sr, sc) = (sr as usize, sc as usize);
8+
9+
if image[sr][sc] == color {
10+
return image;
11+
}
12+
13+
let oc = image[sr][sc];
14+
image[sr][sc] = color;
15+
16+
let mut q = VecDeque::new();
17+
q.push_back((sr, sc));
18+
19+
let dirs = [-1, 0, 1, 0, -1];
20+
21+
while let Some((i, j)) = q.pop_front() {
22+
for k in 0..4 {
23+
let x = i as isize + dirs[k] as isize;
24+
let y = j as isize + dirs[k + 1] as isize;
25+
26+
if x >= 0 && x < m as isize && y >= 0 && y < n as isize {
27+
let (x, y) = (x as usize, y as usize);
28+
if image[x][y] == oc {
29+
q.push_back((x, y));
30+
image[x][y] = color;
31+
}
32+
}
33+
}
34+
}
35+
36+
image
37+
}
38+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
function floodFill(image: number[][], sr: number, sc: number, color: number): number[][] {
2+
if (image[sr][sc] === color) {
3+
return image;
4+
}
5+
6+
const oc = image[sr][sc];
7+
image[sr][sc] = color;
8+
9+
const q: [number, number][] = [];
10+
q.push([sr, sc]);
11+
12+
const dirs = [-1, 0, 1, 0, -1];
13+
const [m, n] = [image.length, image[0].length];
14+
15+
while (q.length > 0) {
16+
const [a, b] = q.shift()!;
17+
for (let k = 0; k < 4; ++k) {
18+
const x = a + dirs[k];
19+
const y = b + dirs[k + 1];
20+
if (x >= 0 && x < m && y >= 0 && y < n && image[x][y] === oc) {
21+
q.push([x, y]);
22+
image[x][y] = color;
23+
}
24+
}
25+
}
26+
27+
return image;
28+
}

0 commit comments

Comments
 (0)
Please sign in to comment.