Skip to content

Commit 39d3850

Browse files
committed
Add solution 130
1 parent a6be258 commit 39d3850

File tree

3 files changed

+250
-0
lines changed

3 files changed

+250
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ Complete solutions to Leetcode problems, updated daily.
5959
| 092 | [Reverse Linked List II](https://github.com/doocs/leetcode/tree/master/solution/092.Reverse%20Linked%20List%20II) | `Linked List` |
6060
| 094 | [Binary Tree Inorder Traversal](https://github.com/doocs/leetcode/tree/master/solution/094.Binary%20Tree%20Inorder%20Traversal) | `Hash Table`, `Stack`, `Tree` |
6161
| 127 | [Word Ladder](https://github.com/doocs/leetcode/tree/master/solution/127.Word%20Ladder) | `Breadth-first Search` |
62+
| 130 | [Surrounded Regions](https://github.com/doocs/leetcode/tree/master/solution/130.Surrounded%20Regions) | `Depth-first Search`, `Breadth-first Search`, `Union Find` |
6263
| 144 | [Binary Tree Preorder Traversal](https://github.com/doocs/leetcode/tree/master/solution/144.Binary%20Tree%20Preorder%20Traversal) | `Stack`, `Tree` |
6364
| 150 | [Evaluate Reverse Polish Notation](https://github.com/doocs/leetcode/tree/master/solution/150.Evaluate%20Reverse%20Polish%20Notation) | `Stack` |
6465
| 153 | [Find Minimum in Rotated Sorted Array](https://github.com/doocs/leetcode/tree/master/solution/153.Find%20Minimum%20in%20Rotated%20Sorted%20Array) | `Array`, `Binary Search` |
+139
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
## 被围绕的区域
2+
### 题目描述
3+
4+
给定一个二维的矩阵,包含 `'X'``'O'`**字母 O**)。
5+
6+
找到所有被 `'X'` 围绕的区域,并将这些区域里所有的 `'O'``'X'` 填充。
7+
8+
**示例:**
9+
```
10+
X X X X
11+
X O O X
12+
X X O X
13+
X O X X
14+
```
15+
16+
运行你的函数后,矩阵变为:
17+
```
18+
X X X X
19+
X X X X
20+
X X X X
21+
X O X X
22+
```
23+
24+
**解释:**
25+
26+
被围绕的区间不会存在于边界上,换句话说,任何边界上的 `'O'` 都不会被填充为 `'X'`。 任何不在边界上,或不与边界上的 `'O'` 相连的 `'O'` 最终都会被填充为 `'X'`。如果两个元素在水平或垂直方向相邻,则称它们是“相连”的。
27+
28+
### 解法
29+
逆向思维,从上下左右四个边缘的有效点`'O'`往里搜索,将搜索到的有效点修改为`'Y'`。最后,剩下的`'O'`就是被`'X'`包围的,将它们修改为`'X'`,将`'Y'`修改回`'O'`
30+
31+
```java
32+
class Solution {
33+
34+
/**
35+
* 坐标点
36+
*/
37+
private class Point {
38+
int x;
39+
int y;
40+
41+
public Point(int x, int y) {
42+
this.x = x;
43+
this.y = y;
44+
}
45+
}
46+
47+
public void solve(char[][] board) {
48+
if (board == null || board.length < 3 || board[0].length < 3) {
49+
return;
50+
}
51+
52+
int m = board.length;
53+
int n = board[0].length;
54+
55+
// top & bottom
56+
for (int i = 0; i < n; ++i) {
57+
bfs(board, 0, i);
58+
bfs(board, m - 1, i);
59+
}
60+
61+
// left & right
62+
for (int i = 1; i < m - 1; ++i) {
63+
bfs(board, i, 0);
64+
bfs(board, i, n - 1);
65+
}
66+
67+
for (int i = 0; i < m; ++i) {
68+
for (int j = 0; j < n; ++j) {
69+
if (board[i][j] == 'O') {
70+
board[i][j] = 'X';
71+
} else if (board[i][j] == 'Y') {
72+
board[i][j] = 'O';
73+
}
74+
}
75+
}
76+
}
77+
78+
/**
79+
* 广度优先搜索
80+
* @param board
81+
* @param i
82+
* @param j
83+
*/
84+
private void bfs(char[][] board, int i, int j) {
85+
Queue<Point> queue = new LinkedList<>();
86+
if (isValid(board, i, j)) {
87+
// 遇到'O',修改为'Y'
88+
board[i][j] = 'Y';
89+
queue.offer(new Point(i, j));
90+
}
91+
92+
while (!queue.isEmpty()) {
93+
Point p = queue.poll();
94+
// 获取下一层所有有效坐标点
95+
List<Point> points = getNextLevelValidPoints(board, p.x, p.y);
96+
97+
for (Point point : points) {
98+
queue.offer(point);
99+
}
100+
}
101+
102+
}
103+
104+
/**
105+
* 获取下一层所有有效坐标点,将这些坐标点修改为 'Y' 并返回
106+
* @param board
107+
* @param i
108+
* @param j
109+
* @return list
110+
*/
111+
private List<Point> getNextLevelValidPoints(char[][] board, int i, int j) {
112+
List<Point> points = new ArrayList<>();
113+
Point[] arr = new Point[] { new Point(i - 1, j), new Point(i + 1, j), new Point(i, j - 1),
114+
new Point(i, j + 1) };
115+
for (Point point : arr) {
116+
if (isValid(board, point.x, point.y)) {
117+
board[point.x][point.y] = 'Y';
118+
points.add(point);
119+
}
120+
}
121+
return points;
122+
}
123+
124+
/**
125+
* 判断坐标是否有效
126+
* @param board
127+
* @param i
128+
* @param j
129+
* @return boolean
130+
*/
131+
private boolean isValid(char[][] board, int i, int j) {
132+
int m = board.length;
133+
int n = board[0].length;
134+
// 当前坐标对应的值是'O',才算有效
135+
return (i < 0 || i > m - 1 || j < 0 || j > n - 1 || board[i][j] != 'O') ? false : true;
136+
}
137+
138+
}
139+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
class Solution {
2+
3+
/**
4+
* 坐标点
5+
*/
6+
private class Point {
7+
int x;
8+
int y;
9+
10+
public Point(int x, int y) {
11+
this.x = x;
12+
this.y = y;
13+
}
14+
}
15+
16+
public void solve(char[][] board) {
17+
if (board == null || board.length < 3 || board[0].length < 3) {
18+
return;
19+
}
20+
21+
int m = board.length;
22+
int n = board[0].length;
23+
24+
// top & bottom
25+
for (int i = 0; i < n; ++i) {
26+
bfs(board, 0, i);
27+
bfs(board, m - 1, i);
28+
}
29+
30+
// left & right
31+
for (int i = 1; i < m - 1; ++i) {
32+
bfs(board, i, 0);
33+
bfs(board, i, n - 1);
34+
}
35+
36+
for (int i = 0; i < m; ++i) {
37+
for (int j = 0; j < n; ++j) {
38+
if (board[i][j] == 'O') {
39+
board[i][j] = 'X';
40+
} else if (board[i][j] == 'Y') {
41+
board[i][j] = 'O';
42+
}
43+
}
44+
}
45+
}
46+
47+
/**
48+
* 广度优先搜索
49+
*
50+
* @param board
51+
* @param i
52+
* @param j
53+
*/
54+
private void bfs(char[][] board, int i, int j) {
55+
Queue<Point> queue = new LinkedList<>();
56+
if (isValid(board, i, j)) {
57+
// 遇到'O',修改为'Y'
58+
board[i][j] = 'Y';
59+
queue.offer(new Point(i, j));
60+
}
61+
62+
while (!queue.isEmpty()) {
63+
Point p = queue.poll();
64+
// 获取下一层所有有效坐标点
65+
List<Point> points = getNextLevelValidPoints(board, p.x, p.y);
66+
67+
for (Point point : points) {
68+
queue.offer(point);
69+
}
70+
}
71+
72+
}
73+
74+
/**
75+
* 获取下一层所有有效坐标点,将这些坐标点修改为 'Y' 并返回
76+
*
77+
* @param board
78+
* @param i
79+
* @param j
80+
* @return list
81+
*/
82+
private List<Point> getNextLevelValidPoints(char[][] board, int i, int j) {
83+
List<Point> points = new ArrayList<>();
84+
Point[] arr = new Point[] { new Point(i - 1, j), new Point(i + 1, j), new Point(i, j - 1),
85+
new Point(i, j + 1) };
86+
for (Point point : arr) {
87+
if (isValid(board, point.x, point.y)) {
88+
board[point.x][point.y] = 'Y';
89+
points.add(point);
90+
}
91+
}
92+
return points;
93+
}
94+
95+
/**
96+
* 判断坐标是否有效
97+
*
98+
* @param board
99+
* @param i
100+
* @param j
101+
* @return boolean
102+
*/
103+
private boolean isValid(char[][] board, int i, int j) {
104+
int m = board.length;
105+
int n = board[0].length;
106+
// 当前坐标对应的值是'O',才算有效
107+
return (i < 0 || i > m - 1 || j < 0 || j > n - 1 || board[i][j] != 'O') ? false : true;
108+
}
109+
110+
}

0 commit comments

Comments
 (0)