1、矩阵 - 力扣(LeetCode)
思路:
- 首先创建一个dist数组,将dist数组初始化为-1,表示该位置没有被搜索和记录该位置的值
- 然后再遍历mat数组,将数组中的 0 添加到队列中,并且修改dist对应位置的值为0
- 然后就依次往外拓展,每次新拓展的点的值就是dist位置的值加一
- 代码:
class Solution { int[] dx = {0, 0, -1, 1}; int[] dy = {1, -1, 0, 0}; public int[][] updateMatrix(int[][] mat) { //1、创建一个dist数组,并且初始化为-1 int[][] dist = new int[mat.length][mat[0].length]; for(int i = 0; i < mat.length; i++){ for(int j = 0; j < mat[0].length; j++){ dist[i][j] = -1; } } //2、遍历mat数组,将0位置加入队列中,并且修改dist对应位置的值为0 Queue<int[]> q = new LinkedList<>(); for(int i = 0; i < mat.length; i++){ for(int j = 0; j < mat[0].length; j++){ if(mat[i][j] == 0){ q.offer(new int[]{i, j}); dist[i][j] = 0; } } } //3、向外一层一层的拓展 while(!q.isEmpty()){ int[] t = q.poll(); int a = t[0]; int b = t[1]; for(int i = 0; i < 4; i++){ int x = a + dx[i]; int y = b + dy[i]; if(x >= 0 && x < mat.length && y >= 0 && y < mat[0].length && dist[x][y] == -1){ q.offer(new int[]{x, y}); dist[x][y] = dist[a][b] + 1; } } } return dist; } }
2、飞地的数量 - 力扣(LeetCode)
思路:
- 要求被0包围的1 的数量,我们可以反过来,先求出边界上的1和其相联的1,标记一下
- 然后再遍历数组,剩下没有被标记的1就是我们要求的1,统计其数量
- 代码:
class Solution { int[] dx = {0, 0, -1, 1}; int[] dy = {1, -1, 0, 0}; public int numEnclaves(int[][] grid) { int m = grid.length; int n = grid[0].length; boolean[][] vis = new boolean[m][n]; Queue<int[]> q = new LinkedList<>(); //1、将边界的1加入到队列中 for(int i = 0; i < m; i++){ if(grid[i][0] == 1){ q.offer(new int[]{i, 0}); vis[i][0] = true; } if(grid[i][n-1] == 1){ q.offer(new int[]{i, n - 1}); vis[i][n-1] = true; } } for(int i = 0; i < n; i++){ if(grid[0][i] == 1){ q.offer(new int[]{0, i}); vis[0][i] = true; } if(grid[m-1][i] == 1){ q.offer(new int[]{m-1, i}); vis[m-1][i] = true; } } //2、遍历队列,向外拓展 while(!q.isEmpty()){ int[] t = q.poll(); int a = t[0]; int b = t[1]; for(int i = 0; i < 4; i++){ int x = a + dx[i]; int y = b + dy[i]; if(x >= 0 && y >= 0 && x < m & y < n && grid[x][y] == 1 && !vis[x][y]){ q.offer(new int[]{x, y}); vis[x][y] = true; } } } //3、提取结果 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++; } } } return ret; } }
3、地图中的最高点 - 力扣(LeetCode)
思路:
- 首先创建一个dist数组,初始化为-1,表示没有搜索过的
- 让遍历isWater数组,将值为1 的位置添加到队列中,并且修改dist对应位置的值为0
- 最后进行多源bfs遍历
- 代码:
class Solution { int[] dx = {0, 0, -1, 1}; int[] dy = {1, -1, 0, 0}; public int[][] highestPeak(int[][] isWater) { int m = isWater.length; int n = isWater[0].length; int[][] dist = new int[m][n]; Queue<int[]> q = new LinkedList<>(); //1、将所有源点加入到队列 for(int i = 0; i < m; i++){ for(int j = 0; j < n; j++){ //初始化dist数组 dist[i][j] = -1; if(isWater[i][j] == 1){ dist[i][j] = 0; q.offer(new int[]{i, j}); } } } //2、多源bfs while(!q.isEmpty()){ int[] t = q.poll(); int a = t[0]; int b = t[1]; for(int i = 0; i < 4; i++){ int x = a + dx[i]; int y = b + dy[i]; if(x >= 0 && y >= 0 && x < m && y < n && dist[x][y] == -1){ //当前位置的值就是原来拓展位置的值 + 1 dist[x][y] = dist[a][b] + 1; q.offer(new int[]{x, y}); } } } return dist; } }
4、地图分析 - 力扣(LeetCode)
思路:
- 我们可以从陆地开始,遍历距离,
- 代码:
class Solution { int[] dx = {0, 0, -1, 1}; int[] dy = {1, -1, 0, 0}; public int maxDistance(int[][] grid) { int m = grid.length; int n = grid[0].length; int[][] dist = new int[m][n]; Queue<int[]> q = new LinkedList<>(); //1、将多个源点入队 for(int i = 0; i < m; i++){ for(int j = 0; j < n; j++){ dist[i][j] = -1; if(grid[i][j] == 1){ dist[i][j] = 0; q.offer(new int[]{i, j}); } } } //2、多源bfs int ret = -1; while(!q.isEmpty()){ int[] t = q.poll(); int a = t[0]; int b = t[1]; for(int i = 0; i < 4; i++){ int x = a + dx[i]; int y = b + dy[i]; if(x >= 0 && y >= 0 && x < m && y < n && dist[x][y] == -1){ dist[x][y] = dist[a][b] + 1; q.offer(new int[]{x, y}); ret = Math.max(ret, dist[x][y]); } } } return ret; } }