FloodFill
泛洪填充演算法(Flood Fill Algorithm)泛洪填充演算法又稱洪水填充演算法是在很多圖形繪制軟體中常用的填充演算法,最熟悉不過就是 windows paint的油漆桶功能,演算法的原理很簡單,就是從一個點開始附近像素點,填充成新的顏色,直到封閉區域內的所有像素點都被填充新顏色為止,泛紅填充實作最常見有四鄰域像素填充法,八鄰域像素填充法,基于掃描線的像素填充方法,根據實作又可以分為遞回與非遞回(基于堆疊),
733. 影像渲染
方法1:DFS
- 當當前的位置的顏色和開始位置
(sr,sc)的顏色不同時,不能繼續dfs - 如果一開始的時候,要修改的目標顏色和開始位置的顏色的值相同,不需要修改
imgage
int[][] dirs = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
int R, C;
public int[][] floodFill(int[][] image, int sr, int sc, int newColor) {
int oldColor = image[sr][sc];
if (oldColor == newColor) return image;
R = image.length;
C = image[0].length;
dfs(image, sr, sc, newColor, oldColor);
return image;
}
public void dfs(int[][] image, int r, int c, int newColor, int oldColor) {
if (!inArea(r, c)) return;
if (image[r][c] != oldColor) return;
image[r][c] = newColor;
for (int[] d : dirs) {
int nr = r + d[0], nc = c + d[1];
dfs(image, nr, nc, newColor, oldColor);
}
}
public boolean inArea(int r, int c) {
return r >= 0 && r < R && c >= 0 && c < C;
}
方法2:BFS
int[][] dirs = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
int R, C;
public int[][] floodFill(int[][] image, int sr, int sc, int newColor) {
int oldColor = image[sr][sc];
if (oldColor == newColor) return image;
R = image.length;
C = image[0].length;
Queue<int[]> queue = new LinkedList<>();
queue.offer(new int[]{sr, sc});
image[sr][sc] = newColor;
while (!queue.isEmpty()) {
int[] p = queue.poll();
for (int[] d : dirs) {
int nr = p[0] + d[0], nc = p[1] + d[1];
if (!inArea(nr, nc)) continue;
if (image[nr][nc] == oldColor) {
image[nr][nc] = newColor;
queue.offer(new int[]{nr, nc});
}
}
}
return image;
}
public boolean inArea(int r, int c) {
return r >= 0 && r < R && c >= 0 && c < C;
}
1034. 邊框著色
方法1:DFS+計數
- dfs回傳的值是0或者1
- 當如果不是和
oldColor相同的顏色,回傳1 - 當不在區域范圍或者當前的
(r,c)點被訪問過,回傳0
- 當如果不是和
- 當cnt<4時,說明有一個方向是可以突圍的,是和外面是聯通的,不是被當前點的同類顏色所包圍
int[][] dirs = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
int R, C;
boolean[][] visited;
int oldColor;
public int[][] colorBorder(int[][] grid, int r0, int c0, int newColor) {
R = grid.length;
C = grid[0].length;
visited = new boolean[R][C];
oldColor = grid[r0][c0];
dfs(grid, r0, c0, newColor);
return grid;
}
public int dfs(int[][] grid, int r, int c, int newColor) {
if (!inArea(r, c)) return 0;
if (visited[r][c]) return 1;
if (grid[r][c] != oldColor) return 0;
visited[r][c] = true;
int cnt = 0;
for (int[] d : dirs) {
int nr = r + d[0], nc = c + d[1];
cnt += dfs(grid, nr, nc, newColor);
}
if (cnt < 4) grid[r][c] = newColor;
return 1;
}
public boolean inArea(int r, int c) {
return r >= 0 && r < R && c >= 0 && c < C;
}
方法2:DFS+翻轉成負數
思路圖片來自國際站
- 在dfs的程序中,將其翻轉成負數,在結束的時候,翻轉負數成正數
- 下面的思路與下圖大體相當,需要開一個額外的
res二維陣列 res需要重新開地址賦值

int[][] dirs = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
int R, C;
int[][] res;
public int[][] colorBorder(int[][] grid, int r0, int c0, int color) {
R = grid.length;
C = grid[0].length;
res = new int[R][C];
for (int r = 0; r < R; r++)
for (int c = 0; c < C; c++)
res[r][c] = grid[r][c];
dfs(grid, r0, c0, color);
return res;
}
public void dfs(int[][] grid, int r, int c, int color) {
res[r][c] *= -1;
boolean isEdge = false;
boolean f = false;
for (int[] d : dirs) {
int nr = r + d[0], nc = c + d[1];
if (d[0] == -1) System.out.printf("上\n");
if (d[0] == 1) System.out.printf("下\n");
if (d[1] == -1) System.out.printf("左\n");
if (d[1] == 1) System.out.printf("右\n");
//當不在區域范圍內或者當前顏色與旁邊的顏色不同時 如下面的例子1
if (!inArea(nr, nc) || grid[r][c] != grid[nr][nc]) {
isEdge = true;
}
//res[nr][nc]首次翻轉的時候(變成負數)一定會進下面的dfs,當再次被翻轉后,其變成與grid的原坐標相同的時候,不會再進
if (inArea(nr, nc) && res[nr][nc] == grid[r][c]) {
dfs(grid, nr, nc, color);
}
}
res[r][c] *= -1;
if (isEdge) res[r][c] = color;
}
public boolean inArea(int r, int c) {
return r >= 0 && r < R && c >= 0 && c < C;
}
例1
當在(0,3)位置,掃其右側的(0,4)位置時,滿足
grid[r][c] != grid[nr][nc]
[[1,2,1,2,1,2],[2,2,2,2,1,2],[1,2,2,2,1,2]]
1
3
1
方法3:BFS
int[][] dirs = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
int R, C;
public int[][] colorBorder(int[][] grid, int r0, int c0, int color) {
R = grid.length;
C = grid[0].length;
int oldColor = grid[r0][c0];
boolean[][] visited = new boolean[R][C];
Queue<int[]> queue = new LinkedList<>();
queue.offer(new int[]{r0, c0});
visited[r0][c0] = true;
while (!queue.isEmpty()) {
int[] p = queue.poll();
int r = p[0], c = p[1];
if (isBorder(r, c)) grid[r][c] = color;
for (int[] d : dirs) {
if (d[0] == -1) System.out.printf("上\n");
if (d[0] == 1) System.out.printf("下\n");
if (d[1] == -1) System.out.printf("左\n");
if (d[1] == 1) System.out.printf("右\n");
int nr = r + d[0], nc = c + d[1];
System.out.printf("(%d,%d)<--->(%d,%d)\n", r, c, nr, nc);
if (!inArea(nr, nc) || visited[nr][nc]) continue;
if (grid[nr][nc] == oldColor) {//挨著的點不是原來的oldColor,當前點便是異類
queue.offer(new int[]{nr, nc});
visited[nr][nc] = true;
} else {
grid[r][c] = color;
}
}
}
return grid;
}
//注意是或
public boolean isBorder(int r, int c) {
return r == 0 || r == R - 1 || c == 0 || c == C - 1;
}
public boolean inArea(int r, int c) {
return r >= 0 && r < R && c >= 0 && c < C;
}
配的例子
int[][] grid = new int[][]{
{1, 1, 1, 1, 2, 2},
{3, 3, 3, 3, 2, 2},
{3, 3, 3, 2, 3, 3},
{3, 3, 2, 3, 3, 3},
{3, 2, 2, 2, 3, 3},
{3, 2, 2, 2, 3, 3},
{3, 3, 2, 2, 3, 3}
};
int color = 4;
int r0 = 5, c0 = 1;
785. 判斷二分圖
這個問題可以抽象為:給定一個無向圖,判斷是否能找到一個使用兩種顏色的著色方案,使每條邊連接的兩點顏色均不同
方法1:DFS染色
public boolean isBipartite(int[][] graph) {
int[] visited = new int[graph.length];
for (int i = 0; i < graph.length; i++) {
//當前點沒有被訪問過且染色失敗,回傳false
if (visited[i] == 0 && !dfs(graph, i, 1, visited)) return false;
}
return true;
}
/**
* @param graph 圖
* @param curr 當前處理的頂點
* @param color 當前頂點即將被染的顏色
* @param visited 記錄頂點是否被訪問過
* @return 成功染色,回傳true,失敗染色回傳false
*/
public boolean dfs(int[][] graph, int curr, int color, int[] visited) {
if (visited[curr] != 0) {
return visited[curr] == color;
}
visited[curr] = color;
for (int next : graph[curr]) {
if (!dfs(graph, next, -color, visited)) return false;
}
return true;
}
方法2:BFS染色
public boolean isBipartite(int[][] graph) {
int[] v = new int[graph.length];
for (int i = 0; i < graph.length; i++) {
//對沒有染色并且有鄰居的進行下面的回圈
if (v[i] == 0 && graph[i].length > 0) {
Queue<Integer> q = new LinkedList<>();
q.offer(i);
v[i] = 1;
while (!q.isEmpty()) {
int size = q.size();
for (int j = 0; j < size; j++) {
int curr = q.poll();
for (int next : graph[curr]) {
//如果curr的鄰居處于沒有被染色的狀態,染上一與curr相反的顏色,curr為1,next為-1,curr為-1,next為1
if (v[next] == 0) {
q.offer(next);
v[next] = -1 * v[curr];
}
//這時候next已經染上色了,開始對其染色進行判斷,如果next與curr同色,不符合題意
else if (v[curr] == v[next]) {
return false;
}
}
}
}
}
}
return true;
}
886. 可能的二分法
- 需要構建圖,其他的模板類似于785二分圖這題
方法1:DFS染色
- 構造圖,其余的和785一毛一樣
public boolean possibleBipartition(int N, int[][] dislikes) {
int[] visited = new int[N + 1];
List<Integer>[] graph = new List[N + 1];
for (int i = 1; i <= N; ++i) graph[i] = new ArrayList<>();
for (int[] d : dislikes) {
graph[d[0]].add(d[1]);
graph[d[1]].add(d[0]);
}
for (int i = 1; i <= N; ++i) {
//當前點沒有被訪問過且染色失敗,回傳false
if (visited[i] == 0 && !dfs(graph, i, 1, visited)) return false;
}
return true;
}
/**
* @param graph 圖
* @param curr 當前處理的頂點
* @param color 當前頂點即將被染的顏色
* @param visited 記錄頂點是否被訪問過
* @return 成功染色,回傳true,失敗染色回傳false
*/
public boolean dfs(List<Integer>[] graph, int curr, int color, int[] visited) {
if (visited[curr] != 0) {
return visited[curr] == color;
}
visited[curr] = color;
for (int next : graph[curr]) {
if (!dfs(graph, next, -color, visited)) return false;
}
return true;
}
方法2:BFS染色
public boolean possibleBipartition(int N, int[][] dislikes) {
//v 表示從1 到 N 的節點,其各自的顏色,初始化為0, 兩種顏色 1 和-1
int[] v = new int[N + 1];
//構造圖
List<Integer>[] graph = new List[N + 1];
for (int i = 1; i <= N; ++i) graph[i] = new ArrayList<>();
//無向圖
for (int[] d : dislikes) {
graph[d[0]].add(d[1]);
graph[d[1]].add(d[0]);
}
for (int i = 1; i <= N; ++i) {
if (v[i] != 0) continue;//已經染色的不需要再染色了
Queue<Integer> q = new LinkedList<>();
q.offer(i);
v[i] = 1;//染色1
while (!q.isEmpty()) {
int curr = q.poll();
for (int next : graph[curr]) {
if (v[next] != 0) {//next如果是和curr一樣的顏色,說明是同類,但是他們各自不喜歡,回傳false
if (v[curr] == v[next]) return false;
} else {
q.offer(next);
v[next] = -v[curr];//翻轉next的顏色為curr的相反數
}
}
}
}
return true;
}
番外
構建圖的另外的方式
Map<Integer, Set<Integer>> graph = new HashMap<>();
for (int[] d : dislikes) {
int s = d[0], t = d[1];
graph.putIfAbsent(s, new HashSet<>());
graph.putIfAbsent(t, new HashSet<>());
graph.get(s).add(t);
graph.get(t).add(s);
}
529. 掃雷游戲
方法1:DFS
- 八方向,需要額外多做一個探測地雷的操作
detect
int R, C;
int[][] dirs = new int[][]{{-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}};
public char[][] updateBoard(char[][] board, int[] click) {
R = board.length;
C = board[0].length;
dfs(board, click[0], click[1]);
return board;
}
public void dfs(char[][] board, int r, int c) {
if (!inArea(r, c)) return;
if (board[r][c] == 'M') {
board[r][c] = 'X';
return;
}
if (board[r][c] == 'E') {
detect(board, r, c);
if (board[r][c] == 'B') {
for (int[] d : dirs) {
int nr = r + d[0], nc = c + d[1];
dfs(board, nr, nc);
}
}
}
}
public void detect(char[][] board, int r, int c) {
int bomb = 0;
for (int[] d : dirs) {
int nr = r + d[0], nc = c + d[1];
if (inArea(nr, nc) && board[nr][nc] == 'M') bomb++;
}
board[r][c] = bomb > 0 ? (char) (bomb + '0') : 'B';
}
private boolean inArea(int r, int c) {
return r >= 0 && r < R && c >= 0 && c < C;
}
方法2:BFS
- 用
visited控制重復訪問
int R, C;
int[][] dirs = new int[][]{{-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}};
public char[][] updateBoard(char[][] board, int[] click) {
R = board.length;
C = board[0].length;
int sr = click[0], sc = click[1];
if (board[sr][sc] == 'M') {
board[sr][sc] = 'X';
return board;
}
bfs(board,sr,sc);
return board;
}
public void bfs(char[][] board, int r, int c) {
boolean[][] visited = new boolean[R][C];
Queue<int[]> q = new LinkedList<>();
q.offer(new int[]{r, c});
visited[r][c] = true;
while (!q.isEmpty()) {
int[] curr = q.poll();
int currR = curr[0], currC = curr[1];
detect(board, currR, currC);
if (board[currR][currC] == 'B') {
for (int[] d : dirs) {
int nextR = currR + d[0], nextC = currC + d[1];
if (inArea(nextR, nextC) && !visited[nextR][nextC]) {
q.offer(new int[]{nextR, nextC});
visited[nextR][nextC] = true;
}
}
}
}
}
private boolean inArea(int r, int c) {
return r >= 0 && r < R && c >= 0 && c < C;
}
public void detect(char[][] board, int r, int c) {
int bomb = 0;
for (int[] d : dirs) {
int nr = r + d[0], nc = c + d[1];
if (inArea(nr, nc) && board[nr][nc] == 'M') bomb++;
}
board[r][c] = bomb > 0 ? (char) (bomb + '0') : 'B';
}
200. 島嶼數量
島嶼問題之島嶼的數量Eighty-eight Butterfly
827. 最大人工島
島嶼問題之最大人工島Danaus Genutia
695. 島嶼的最大面積
島嶼問題之島嶼的周長面積Morpho Cypris Aphrodite
463. 島嶼的周長
島嶼問題之島嶼的周長面積Morpho Cypris Aphrodite
1254. 統計封閉島嶼的數目
島嶼問題之不同島嶼的數量Monarch Butterfly
130. 被圍繞的區域
島嶼問題之被圍繞的區域[Cicada]
289. 生命游戲
方法1:BFS染色
int R, C;
int[][] dirs = new int[][]{{-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}};
public void gameOfLife(int[][] board) {
if (board == null || (board.length == 0 || board[0].length == 0)) return;
R = board.length;
C = board[0].length;
bfs(board, 0, 0);
// PrintUtils.printMatrix(board);
for (int r = 0; r < R; ++r)
for (int c = 0; c < C; ++c)
//被標記的發生翻轉
if (board[r][c] == -1) board[r][c] = 0;
else if (board[r][c] == -2) board[r][c] = 1;
// PrintUtils.printMatrix(board);
}
public void bfs(int[][] board, int sr, int sc) {
boolean[][] visited = new boolean[R][C];
Queue<int[]> q = new LinkedList<>();
q.offer(new int[]{sr, sc});
visited[sr][sc] = true;//標記原始(sr,sc)被訪問過
while (!q.isEmpty()) {
int[] curr = q.poll();
int cr = curr[0], cc = curr[1];//當前點
int cnt = 0;
for (int[] d : dirs) {
int nr = cr + d[0], nc = cc + d[1];
if (!inArea(nr, nc)) continue;
//當前為1 或者我們暫時標記的-1 cnt++
if (board[nr][nc] == 1 || board[nr][nc] == -1) cnt++;
if (visited[nr][nc]) continue;
q.offer(new int[]{nr, nc});
visited[nr][nc] = true;
}
// System.out.printf("(%d,%d)-%d\n", cr, cc, cnt);
if (board[cr][cc] == 1) {//當前細胞為活細胞
if (cnt < 2 || cnt > 3) board[cr][cc] = -1;//<2 >3 兩種情況下需要設定當前的活細胞為死細胞,區別0這種,我們設定為-1
else if (cnt == 2 || cnt == 3) board[cr][cc] = 1;//等于2 等于3 活細胞繼續活著
} else if (board[cr][cc] == 0) {//當前細胞為死細胞
if (cnt == 3) board[cr][cc] = -2;//死細胞復活,區別1這種活細胞,設定為-2
}
}
}
private boolean inArea(int r, int c) {
return r >= 0 && r < R && c >= 0 && c < C;
}
方法2:位操作
來自國際站@yavinci大神,地址在這里
- 可以使用2 bits來存盤這幾種狀態
[2nd bit, 1st bit] = [next state, current state]
//從左到右是第2位,第1位,
- 00 dead (next) <- dead (current) 0(10) //十進制的0
- 01 dead (next) <- live (current) 1(10) //十進制的1
- 10 live (next) <- dead (current) 2(10) //十進制的2
- 11 live (next) <- live (current) 3(10) //十進制的3
-
一些解釋
- 一開始的時候,只有0和1 也就是只有
00和01這兩種二進制狀態 - 注意到第1位的狀態
1st與第2位2nd的狀態是獨立的 - 想象下,所有的細胞從
1st狀態切換到2nd狀態 - 計算當前點從
1st狀態的存活著的鄰居,依據規則設定2nd狀態 - 因為
2nd默認是0,也就是死亡的,沒有必要考慮01->00 - 在結束前,移除
1st狀態,保留2nd的狀態,回傳board執行>> 操作即可
- 一開始的時候,只有0和1 也就是只有
-
檢查每個細胞的
1st狀態,然后根據存活狀態的鄰居數量來設定2nd
01->11 //一開始的時候是存活的,繼續保持存活需要滿足:
board[r][c]== 1 && lives in (2,3)
00->10 //一開始的時候是死亡的,轉成存活需要滿足:
board[r][c]==0 && lives in (3)
位操作小技巧
//獲取當前低位 1st
board[[r][c]&1
//獲取下個狀態位 即高位 2nd
board[r][c]>>1
- 與( & )每一位進行比較,兩位都為1,結果為1,否則為0(-4 & 1 = 0)
1 0 0 1 1 -->(19)[10] 表示10進制中的19
& 1 1 0 0 1 -->(25)[10]
------------------------------
1 0 0 0 1 -->(17)[10]
- 右移( >> ) 整體右移,左邊空出位補零或補1(負數補1,整數補0),右邊位舍棄 (-4 >> 1 = -2)
unsigned int a = 8;
a >> 3;
移位前:0000 0000 0000 0000 0000 0000 0000 1000 -->(8)[10]
移位后:0000 0000 0000 0000 0000 0000 0000 0001 -->(1)[10] 相當于 / 2^3
int a = -8;
a >> 3;
移位前:1111 1111 1111 1111 1111 1111 1111 1000 -->(-8)[10]
移位前:1111 1111 1111 1111 1111 1111 1111 1111 -->(-1)[10]
int R, C;
public void gameOfLife(int[][] board) {
if (board == null || board.length == 0) return;
R = board.length;
C = board[0].length;
PrintUtils.printMatrix(board, true);
for (int r = 0; r < R; r++) {
for (int c = 0; c < C; c++) {
int lives = getLiveNeighbors1(board, r, c);
//一開始的時候,所有的2nd都是0,因此只需要確定2nd是否變成1
// 01 --> 11 做2nd位 3想成是十進制的11
if (board[r][c] == 1 && (lives >= 2 && lives <= 3)) board[r][c] = 3;
//00 --> 10 做2nd位 2想成是十進制的10
if (board[r][c] == 0 && lives == 3) board[r][c] = 2;
}
}
PrintUtils.printMatrix(board, true);
for (int r = 0; r < R; r++) {
for (int c = 0; c < C; c++) {
board[r][c] >>= 1;
}
}
}
public int getLiveNeighbors(int[][] board, int sr, int sc) {
int lives = 0;
//遍歷的時候拿的是sr,sc一圈為1的9個點,有1的+1
for (int r = Math.max(sr - 1, 0); r <= Math.min(sr + 1, R - 1); r++) {
for (int c = Math.max(sc - 1, 0); c <= Math.min(sc + 1, C - 1); c++) {
lives += board[r][c] & 1;
}
}
//去掉自己是1的情況
lives -= board[sr][sc] & 1;
return lives;
}
另外一種求lives的方式:
public int getLiveNeighbors1(int[][] board, int sr, int sc) {
int[][] dirs = new int[][]{{-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}};
int lives = 0;
for (int[] d : dirs) {
int nr = sr + d[0], nc = sc + d[1];
if (!inArea(nr, nc)) continue;
lives += board[nr][nc] & 1;
}
return lives;
}
private boolean inArea(int r, int c) {
return r >= 0 && r < R && c >= 0 && c < C;
}
列印出位操作前后的二進制的狀態
//原始的board
0 1 0
0 0 1
1 1 1
0 0 0
----
//原始的board 二進制
00 01 00
00 00 01
01 01 01
00 00 00
--------------
//位操作后的board 二進制
00 01 00
10 00 11
01 11 11
00 10 00
//取2nd 位的結果即可回傳
1020. 飛地的數量
類似130題 被圍繞的區域
方法1:BFS染色
int[][] dirs = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
int R, C;
public int numEnclaves(int[][] A) {
R = A.length;
C = A[0].length;
PrintUtils.printMatrix(A);
for (int r = 0; r < R; r++) {
for (int c = 0; c < C; c++) {
if (isBoard(r, c) && A[r][c] == 1) {//邊界上的1作為種子來進行擴散
bfs(A, r, c);
}
}
}
//統計1的個數(即封閉的陸地的個數)
int cnt = 0;
for (int r = 0; r < R; r++) {
for (int c = 0; c < C; c++) {
if (A[r][c] == 1) cnt++;
}
}
return cnt;
}
private void bfs(int[][] A, int sr, int sc) {
Queue<int[]> q = new LinkedList<>();
q.offer(new int[]{sr, sc});
A[sr][sc] = 0;//邊緣進來的點是1,染色為0
while (!q.isEmpty()) {
int[] c = q.poll();
int cr = c[0], cc = c[1];
for (int[] d : dirs) {
int nr = cr + d[0], nc = cc + d[1];
if (!inArea(nr, nc)) continue;
if (A[nr][nc] == 1) {//如果當前點是陸地1,翻轉為0
q.offer(new int[]{nr, nc});
A[nr][nc] = 0;
}
}
}
}
//邊緣的點
private boolean isBoard(int r, int c) {
return r == 0 || r == R - 1 || c == 0 || c == C - 1;
}
//在區域內的點
private boolean inArea(int r, int c) {
return r >= 0 && r < R && c >= 0 && c < C;
}
方法2:DFS染色
int[][] dirs = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
int R, C;
public int numEnclaves(int[][] A) {
R = A.length;
C = A[0].length;
for (int r = 0; r < R; r++) {
for (int c = 0; c < C; c++) {
if (isBoard(r, c) && A[r][c] == 1) {
dfs(A, r, c);
}
}
}
//統計1的個數(即封閉的陸地的個數)
int cnt = 0;
for (int r = 0; r < R; r++) {
for (int c = 0; c < C; c++) {
if (A[r][c] == 1) cnt++;
}
}
return cnt;
}
private void dfs(int[][] A, int r, int c) {
if (!inArea(r, c) || A[r][c] != 1) return;
A[r][c] = 0;
for (int[] d : dirs) {
dfs(A, r + d[0], c + d[1]);
}
}
//邊緣的點
private boolean isBoard(int r, int c) {
return r == 0 || r == R - 1 || c == 0 || c == C - 1;
}
//在區域內的點
private boolean inArea(int r, int c) {
return r >= 0 && r < R && c >= 0 && c < C;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/257189.html
標籤:其他
