1、 图像渲染 - 力扣(LeetCode)
思路:
- 代码:
class Solution { int[] dx = {0,0,1,-1}; int[] dy = {1,-1,0,0}; public int[][] floodFill(int[][] image, int sr, int sc, int color) { //统计刚开始[sr,sc]坐标位置的颜色 int prev = image[sr][sc]; //处理便捷情况 if(prev == color){ return image; } int m = image.length; int n = image[0].length; Queue<int[]> q = new LinkedList<>(); q.add(new int[]{sr, sc}); //遍历队列 while(!q.isEmpty()){ int[] t = q.poll(); int a = t[0]; int b = t[1]; image[a][b] = color; //上下左右四个方向 for(int i = 0; i < 4; i++){ int x = a + dx[i]; int y = b + dy[i]; if(x >= 0 && x < m && y >= 0 && y < n && image[x][y] == prev){ q.add(new int[]{x, y}); } } } return image; } }
2、岛屿数量 - 力扣(LeetCode)
思路:
- 寻找相同的连通块,bfs算法,
- 可以找到1之后,就1修改成0,避免重复
- 也可以找到1之后将状态改成true
- 代码:
class Solution { //创建全局变量 int[] dx = {0, 0, 1, -1}; int[] dy = {1, -1, 0, 0}; //创建一个数组标记该位置下的状态 boolean[][] vis; int m, n; public int numIslands(char[][] grid) { m = grid.length; n = grid[0].length; vis = new boolean[m][n]; int ret = 0; for(int i = 0; i < m; i++){ for(int j = 0; j < n; j++){ if(grid[i][j] == '1' && vis[i][j] == false){ ret++; bfs(grid, i, j); } } } return ret; } public void bfs(char[][] grid, int i, int j){ //先将这个位置加入到队列中 Queue<int[]> q = new LinkedList<>(); q.add(new int[]{i, j}); vis[i][j] = true; //遍历上下左右四个方向 while(!q.isEmpty()){ int[] t = q.poll(); int a = t[0], b = t[1]; for(int k = 0; k < 4; k++){ int x = a + dx[k], y = b + dy[k]; if(x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == '1' && vis[x][y] == false){ //添加到队列并且更新状态 q.add(new int[]{x,y}); vis[x][y] = true; } } } } }
3、岛屿的最大面积 - 力扣(LeetCode)
思路:
- 遇上一题的思路一样,只不过是加了一个count来统计最大面积的大小
class Solution { int[] dx = {0, 0, 1, -1}; int[] dy = {1, -1, 0, 0}; boolean[][] vis; int n, m; public int maxAreaOfIsland(int[][] grid) { m = grid.length; n = grid[0].length; vis = new boolean[m][n]; int ret = 0; for(int i = 0; i < m; i++){ for(int j = 0; j < n; j++){ if(grid[i][j] == 1 && !vis[i][j]){ ret = Math.max(ret, bfs(grid, i, j)); } } } return ret; } public int bfs(int[][] g, int i, int j){ int count = 0; Queue<int[]> q = new LinkedList<>(); q.add(new int[]{i,j}); //对传入的坐标的状态进行初始化 vis[i][j] = true; count++; while(!q.isEmpty()){ int[] t = q.poll(); int a = t[0]; int b = t[1]; for(int k = 0; k < 4; k++){ int x = a + dx[k]; int y = b + dy[k]; if(x >= 0 && x < m && y >= 0 && y < n && g[x][y] == 1 && !vis[x][y]){ q.add(new int[]{x,y}); vis[x][y] = true; count++; } } } return count; } }
4、被围绕的区域 - 力扣(LeetCode)
思路:
- 我们先用bfs将边界的O给修改成 点
- 然后再开始修改全部被包围的O
- 最后把点还原成 O
- 代码:
class Solution { int[] dx = {0, 0, 1, -1}; int[] dy = {1, -1, 0, 0}; int m, n; public void solve(char[][] board) { m = board.length; n = board[0].length; //1、先处理边界情况,把边界的O全改成 . for(int i = 0; i < m; i++){ if(board[i][0] == 'O'){ bfs(board, i, 0); } if(board[i][n-1] == 'O'){ bfs(board, i, n-1); } } for(int j = 0; j < n; j++){ if(board[0][j] == 'O'){ bfs(board, 0, j); } if(board[m-1][j] == 'O'){ bfs(board, m-1, j); } } //2、还原 O for(int i = 0; i < m; i++){ for(int j = 0; j < n; j++){ if(board[i][j] == 'O'){ board[i][j] = 'X'; }else if(board[i][j] == '.'){ board[i][j] = 'O'; } } } } public void bfs(char[][] b, int i, int j){ Queue<int[]> q = new LinkedList<>(); q.offer(new int[] {i,j}); b[i][j] = '.'; while(!q.isEmpty()){ int[] t = q.poll(); int a = t[0]; int b1 = t[1]; for(int k = 0; k < 4; k++){ int x = a + dx[k]; int y = b1 + dy[k]; if(x >= 0 && x < m && y >= 0 && y < n && b[x][y] == 'O'){ b[x][y] = '.'; q.offer(new int[] {x, y}); } } } } }