逻辑判断上下左右的新点
int[][] direct = {{0,1},{0,-1},{1,0},{-1,0}};
while(xxx){
int x=当前点x, y= 当前点y
//一个for循环得到四个新点,可以将其当作一种情况进行判断
for (int i = 0; i < 4; i++) {
int nx = direct[i][0] + x, ny = direct[i][1] + y;
逻辑判断新点
if(nx... && ny...) {
}
}
力扣200.岛屿数量
思路:遍历二维数组,碰到1就把所有和1连起来的改成其他数
class Solution {
public int numIslands(char[][] grid) {
int m = grid.length, n = grid[0].length;
int ret = 0;
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
if(grid[i][j] == '1') {
ret++;
//所有的相连的1全改成2;这样下次就找不到它了
bfs(grid,i,j);
//或者
//dfs(grid,i,j);
}
}
}
return ret;
}
void bfs(char[][] grid, int x, int y) {...}
void dfs(char[][] grid, int x, int y) {...}
}
深度优先搜索(DFS):
int[][] direct = {{1,0},{-1,0}, {0,1}, {0,-1}};
//一直往是1的方向走,走过的地方改成1,走到头没路了就回溯到上一个分叉口换条路走
void dfs(char[][] grid, int x, int y) {
int m = grid.length, n = grid[0].length;
grid[x][y] = 0;
for(int i = 0; i < 4; i++) {
int nx = direct[i][0] + x, ny = direct[i][1] + y;
if(nx >=0 && nx < m && ny >= 0 && ny < n && grid[nx][ny] == '1') {
dfs(grid,nx,ny);
}
}
}
由于这道题判断上下左右的x y进入递归的情况较为简单,可以不引入for循环和方向,简化如下
void dfs2(char[][] grid, int x, int y) {
int m = grid.length;
int n = grid[0].length;
if (x < 0 || y < 0 || x >= m || y >= n || grid[x][y] == '0') {
return;
}
grid[x][y] = '0';
dfs2(grid, x - 1, y);
dfs2(grid, x + 1, y);
dfs2(grid, x, y - 1);
dfs2(grid, x, y + 1);
}
广度优先搜索(BFS):
int[][] direct = {{1,0},{-1,0}, {0,1}, {0,-1}};
//广度优先搜索,把1周围是1的改为0
void bfs(char[][] grid, int x, int y) {
int m = grid.length, n = grid[0].length;
Queue<int[]> queue = new LinkedList<>();
queue.add(new int[]{x,y});
grid[x][y] = 0;
while(queue.size() > 0) {
int[] cur = queue.poll();
int curx = cur[0], cury = cur[1];
for(int i = 0; i < 4; i++) {
int nx = direct[i][0] + curx, ny = direct[i][1] + cury;
if(nx >=0 && nx < m && ny >= 0 && ny < n && grid[nx][ny] == '1') {
queue.add(new int[]{nx, ny});
grid[nx][ny] = 0;
}
}
}
}
力扣1034.边界着色
深度优先搜索(DFS):
用递归进行深度优先搜索,一直往一个方向搜索,只要新点是在连通区域,内且
class Solution {
int[][] direct = {{1,0}, {-1,0}, {0,1}, {0,-1}};
List<int[]> bound = new ArrayList<>();
public int[][] colorBorder(int[][] grid, int row, int col, int color) {
int m = grid.length, n = grid[0].length;
boolean[][] vis = new boolean[m][n];
dfs(grid,vis,row, col, grid[row][col]);
for(int i = 0; i < bound.size(); i++) {
grid[bound.get(i)[0]][bound.get(i)[1]] = color;
}
return grid;
}
void dfs(int[][] grid, boolean[][] vis, int x, int y, int orginColor) {
int m = grid.length, n = grid[0].length;
vis[x][y] =true;
boolean isBound = false;
for(int i = 0; i < 4; i++) {
int nx = direct[i][0] + x, ny = direct[i][1] + y;
if(!(nx >=0 && nx < m && ny >=0 && ny < n && grid[nx][ny] == orginColor)){
isBound = true;
}else if(!vis[nx][ny]) {
dfs(grid,vis,nx, ny, orginColor);
}
}
if(isBound){
bound.add(new int[]{x,y});
}
}
}
广度优先搜索(BFS):
用队列保存要遍历的结点,进行广度优先搜索,搜索过的做标记,新点在连通区内且未被访问过这加入队列,回头继续从这个点搜索。记录是边界的点,最后将grid中边界的点改掉。
class Solution {
public int[][] colorBorder(int[][] grid, int row, int col, int color) {
int m = grid.length, n = grid[0].length;
Queue<int[]> queue = new LinkedList<>();
queue.add(new int[]{row, col});
boolean[][] vis = new boolean[m][n];
List<int[]> bound = new ArrayList<>();
int[][] direct = {{0,1},{0,-1},{1,0},{-1,0}};
int oriColor = grid[row][col];
while (queue.size() > 0) {
int[] poll = queue.poll();
int x = poll[0], y = poll[1];
boolean isBound =false;
for (int i = 0; i < 4; i++) {
int nx = direct[i][0] + x, ny = direct[i][1] + y;
//不满足任意一个,说明此点是边界
if(!(nx >=0 && nx < m && ny >= 0 && ny < n && grid[nx][ny] == oriColor)){
isBound = true;
}else if(!vis[nx][ny]) {
vis[nx][ny] = true;
queue.add(new int[]{nx,ny});
}
}
if(isBound){
bound.add(new int[]{x,y});
}
}
for (int i = 0; i < bound.size(); i++) {
grid[bound.get(i)[0]][bound.get(i)[1]] = color;
}
return grid;
}
}