Skip to content

Commit eb0f6a3

Browse files
committed
add some new solution for 733
1 parent 1035969 commit eb0f6a3

File tree

6 files changed

+221
-58
lines changed

6 files changed

+221
-58
lines changed
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
---
2+
weight: 33
3+
bookFlatSection: true
4+
title: "✅ 733. 图像渲染"
5+
description: "733. 图像渲染"
6+
---
7+
8+
# 733. 图像渲染
9+
10+
## 题目描述
11+
12+
{{< button href="https://leetcode-cn.com/problems/flood-fill/" >}}题目地址{{< /button >}}
13+
{{< button href="https://github.com/kylesliu/awesome-golang-algorithm/tree/master/leetcode/701-800/0733.Flood-Fill" >}}代码{{< /button >}}
14+
15+
有一幅以二维整数数组表示的图画,每一个整数表示该图画的像素值大小,数值在 0 到 65535 之间。
16+
17+
给你一个坐标`(sr, sc)`表示图像渲染开始的像素值(行 ,列)和一个新的颜色值`newColor`,让你重新上色这幅图像。
18+
为了完成上色工作,从初始坐标开始,记录初始坐标的上下左右四个方向上像素值与初始坐标相同的相连像素点,接着再记录这四个方向上符合条件的像素点与他们对应四个方向上像素值与初始坐标相同的相连像素点,……,重复该过程。将所有有记录的像素点的颜色值改为新的颜色值。
19+
最后返回经过上色渲染后的图像。
20+
21+
### **示例 1**
22+
23+
```text
24+
输入:
25+
image = [[1,1,1],[1,1,0],[1,0,1]]
26+
sr = 1, sc = 1, newColor = 2
27+
输出: [[2,2,2],[2,2,0],[2,0,1]]
28+
解析:
29+
在图像的正中间,(坐标(sr,sc)=(1,1)),
30+
在路径上所有符合条件的像素点的颜色都被更改成2。
31+
注意,右下角的像素没有更改为2,
32+
因为它不是在上下左右四个方向上与初始点相连的像素点
33+
```
34+
35+
### **限制**
36+
37+
- `image``image[0]`的长度在范围`[1, 50]`内。
38+
- 给出的初始点将满足`0 <= sr < image.length``0 <= sc < image[0].length`
39+
- `image[i][j]``newColor`表示的颜色值在范围`[0, 65535]`内。
40+
41+
## 题解
42+
43+
### 思路 1 : **深度优先搜索 / DFS**
44+
45+
**算法流程:**
46+
47+
基本 DFS 操作,数据会被修改最好保存老的颜色。
48+
49+
**复杂度分析:**
50+
51+
- **时间复杂度** `O(n×m)`,其中 `n``m` 分别是二维数组的行数和列数。最坏情况下需要遍历所有的方格一次。
52+
- **空间复杂度** `O(n×m)`,其中 `n``m` 分别是二维数组的行数和列数。主要为栈空间的开销。
53+
54+
#### 代码
55+
56+
{{< tabs "lc733-01" >}}
57+
{{< tab "Go" >}}
58+
59+
```go
60+
var localDirs = [][2]int{{0, -1}, {0, 1}, {-1, 0}, {1, 0}}
61+
func floodFill(image [][]int, sr int, sc int, newColor int) [][]int {
62+
var dfs func([][]int, int, int, int, int)
63+
dfs = func(image [][]int, r, c, oldColor, newColor int) {
64+
if c < 0 || r < 0 || r >= len(image) || c >= len(image[0]) || image[r][c] != oldColor {
65+
return
66+
}
67+
image[r][c] = newColor
68+
for _, dir := range localDirs {
69+
dfs(image, r+dir[0], c+dir[1], oldColor, newColor)
70+
}
71+
}
72+
if image[sr][sc] != newColor {
73+
dfs(image, sr, sc, image[sr][sc], newColor)
74+
}
75+
return image
76+
}
77+
```
78+
79+
{{< /tab >}}
80+
81+
{{< /tabs >}}
82+
83+
### 思路 2:**广度优先搜索 / BFS**
84+
85+
#### 算法流程
86+
87+
基本 DFS 操作...
88+
89+
#### 复杂度分析
90+
91+
- **时间复杂度** `O(n×m)`,其中 `n``m` 分别是二维数组的行数和列数。最坏情况下需要遍历所有的方格一次。
92+
- **空间复杂度** `O(n×m)`,其中 `n``m` 分别是二维数组的行数和列数。主要为队列的开销。
93+
94+
{{< tabs "lc733-02" >}}
95+
{{< tab "Go" >}}
96+
97+
```go
98+
var localDirs = [][2]int{{0, -1}, {0, 1}, {-1, 0}, {1, 0}}
99+
func floodFill(image [][]int, sr int, sc int, newColor int) [][]int {
100+
oldColor := image[sr][sc]
101+
if oldColor == newColor {
102+
return image
103+
}
104+
n, m := len(image), len(image[0])
105+
queue := [][]int{}
106+
queue = append(queue, []int{sr, sc})
107+
image[sr][sc] = newColor
108+
for len(queue) > 0 {
109+
tmp := queue[0]
110+
queue = queue[1:]
111+
for _, dir := range localDirs {
112+
r, c := tmp[0]+dir[0], tmp[1]+dir[1]
113+
if r >= 0 && r < n && c >= 0 && c < m && image[r][c] == oldColor {
114+
queue = append(queue, []int{r, c})
115+
image[r][c] = newColor
116+
}
117+
}
118+
}
119+
return image
120+
}
121+
```
122+
123+
{{< /tab >}}
124+
125+
{{< /tabs >}}
126+
127+
## 总结
128+
129+
如果你同我一样热爱数据结构、算法、LeetCode,可以关注我 GitHub 上的 算法 题解:[awesome-golang-algorithm](https://github.com/kylesliu/awesome-golang-algorithm)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
weight: 7
3+
title: "0701-0800"
4+
bookCollapseSection: true
5+
---
6+
7+
# 0701-0800

leetcode/701-800/0733.Flood-Fill/README.md

Lines changed: 0 additions & 36 deletions
This file was deleted.

leetcode/701-800/0733.Flood-Fill/Solution.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,43 @@ func Solution(image [][]int, sr, sc, newColor int) [][]int {
2828
floodFillDFS(image, visited, sr, sc, rows, cols, image[sr][sc], newColor)
2929
return image
3030
}
31+
32+
func floodFill_dfs(image [][]int, sr int, sc int, newColor int) [][]int {
33+
var dfs func([][]int, int, int, int, int)
34+
dfs = func(image [][]int, r, c, oldColor, newColor int) {
35+
if c < 0 || r < 0 || r >= len(image) || c >= len(image[0]) || image[r][c] != oldColor {
36+
return
37+
}
38+
image[r][c] = newColor
39+
for _, dir := range localDirs {
40+
dfs(image, r+dir[0], c+dir[1], oldColor, newColor)
41+
}
42+
}
43+
if image[sr][sc] != newColor {
44+
dfs(image, sr, sc, image[sr][sc], newColor)
45+
}
46+
return image
47+
}
48+
49+
func floodFill_bfs(image [][]int, sr int, sc int, newColor int) [][]int {
50+
oldColor := image[sr][sc]
51+
if oldColor == newColor {
52+
return image
53+
}
54+
n, m := len(image), len(image[0])
55+
queue := [][]int{}
56+
queue = append(queue, []int{sr, sc})
57+
image[sr][sc] = newColor
58+
for len(queue) > 0 {
59+
tmp := queue[0]
60+
queue = queue[1:]
61+
for _, dir := range localDirs {
62+
r, c := tmp[0]+dir[0], tmp[1]+dir[1]
63+
if r >= 0 && r < n && c >= 0 && c < m && image[r][c] == oldColor {
64+
queue = append(queue, []int{r, c})
65+
image[r][c] = newColor
66+
}
67+
}
68+
}
69+
return image
70+
}
Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,56 @@
11
package Solution
22

33
import (
4+
"fmt"
45
"reflect"
5-
"strconv"
6+
"runtime"
7+
"strings"
68
"testing"
9+
10+
"github.com/stretchr/testify/assert"
711
)
812

13+
// Solution func Info
14+
type SolutionFuncType func([][]int, int, int, int) [][]int
15+
16+
var SolutionFuncList = []SolutionFuncType{
17+
Solution,
18+
floodFill_dfs,
19+
floodFill_bfs,
20+
}
21+
22+
// Test case info struct
23+
type Case struct {
24+
name string
25+
image [][]int
26+
sr, sc, newColor int
27+
expect [][]int
28+
}
29+
30+
// Test case
31+
var cases = []Case{
32+
{"TestCase 1", [][]int{{1, 1, 1}, {1, 1, 0}, {1, 0, 1}}, 1, 1, 2, [][]int{{2, 2, 2}, {2, 2, 0}, {2, 0, 1}}},
33+
{"TestCase 2", [][]int{{1}}, 0, 0, 2, [][]int{{2}}},
34+
{"TestCase 3", [][]int{{1, 1, 1}, {1, 0, 1}, {1, 1, 1}}, 1, 1, 2, [][]int{{1, 1, 1}, {1, 2, 1}, {1, 1, 1}}},
35+
{"TestCase 4", [][]int{{0, 0, 0}, {0, 0, 0}}, 0, 0, 2, [][]int{{2, 2, 2}, {2, 2, 2}}},
36+
}
37+
38+
// TestSolution Run test case for all solutions
939
func TestSolution(t *testing.T) {
10-
// 测试用例
11-
cases := []struct {
12-
name string
13-
inputs [][]int
14-
sr, sc, newColor int
15-
expect [][]int
16-
}{
17-
{"TestCase1", [][]int{{1, 1, 1}, {1, 1, 0}, {1, 0, 1}}, 1, 1, 2, [][]int{{2, 2, 2}, {2, 2, 0}, {2, 0, 1}}},
18-
{"TestCase2", [][]int{{1}}, 0, 0, 2, [][]int{{2}}},
19-
{"TestCase3", [][]int{{1, 1, 1}, {1, 0, 1}, {1, 1, 1}}, 1, 1, 2, [][]int{{1, 1, 1}, {1, 2, 1}, {1, 1, 1}}},
20-
{"TestCase4", [][]int{{0, 0, 0}, {0, 0, 0}}, 0, 0, 2, [][]int{{2, 2, 2}, {2, 2, 2}}},
21-
}
40+
ast := assert.New(t)
2241

23-
// 开始测试
24-
for i, c := range cases {
25-
t.Run(c.name+" "+strconv.Itoa(i), func(t *testing.T) {
26-
got := Solution(c.inputs, c.sr, c.sc, c.newColor)
27-
if !reflect.DeepEqual(got, c.expect) {
28-
t.Fatalf("expected: %v, but got: %v, with inputs-image: %v, input-sr: %v, input-sc: %v",
29-
c.expect, got, c.inputs, c.sr, c.sc)
30-
}
31-
})
42+
for _, f := range SolutionFuncList {
43+
funcName := strings.Split(runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name(), ".")[1]
44+
for _, c := range cases {
45+
t.Run(fmt.Sprintf("%s %s", funcName, c.name), func(t *testing.T) {
46+
image := [][]int{}
47+
for _, v := range c.image {
48+
image = append(image, append([]int{}, v...))
49+
}
50+
got := f(image, c.sc, c.sc, c.newColor)
51+
ast.Equal(c.expect, got,
52+
"func: %v case: %v ", funcName, c.name)
53+
})
54+
}
3255
}
3356
}
-17.2 KB
Binary file not shown.

0 commit comments

Comments
 (0)