深度优先搜索
如图所示,深度优先搜索DFS对新节点立即执行搜索,因此新节点都向下一层。
而广度优先搜索BFS先用队列存储新节点,等当前层的新节点都搜索完毕之后再搜索下一层节点。

图片链接
leetcode695
分析
使用2个函数。主函数统计比较每块岛屿的面积,子函数通过深度优先搜索计算每块岛屿的面积。
深度优先搜索是相对于广度优先搜索而言的。广度优先搜索考虑层级关系,
每块土地都只会被归纳到1个岛屿,被统计1次。因此为了防止重复计算,将统计过的土地置为0.
源码
class Solution {
int[][] directions = {{1,0}, {-1,0},{0,1}, {0,-1}}; // 预定义的四个方向
public int maxAreaOfIsland(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
int maxArea = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == 1) {
int curArea = dfs(grid, i, j); // 计算当前岛屿的大小
maxArea = Math.max(maxArea, curArea);
}
}
}
return maxArea;
}
private int dfs(int[][] grid, int curI, int curJ) {
if (curI < 0 || curI >= grid.length || curJ < 0 || curJ >= grid[0].length || grid[curI][curJ] == 0) {
return 0; // 参数校验
}
int curArea = 1;
grid[curI][curJ] = 0; // 防止重复计算
for (int i = 0; i < 4; i++) {
int nextI = curI + directions[i][0];
int nextJ = curJ + directions[i][1];
curArea += dfs(grid, nextI, nextJ);
}
return curArea;
}
}
leetcode547
分析
矩阵是对称矩阵。每个城市必定与自己相连,因此主对角线元素必定为1.
源码
class Solution {
public int findCircleNum(int[][] isConnected) {
int provinces = 0;
boolean[] visited = new boolean[isConnected.length];
for (int i = 0; i < isConnected.length; i++) {
if (!visited[i]) {
dfs(visited, isConnected, i);
provinces++;
}
}
return provinces;
}
private void dfs(boolean[] visited, int[][] isConnected, int cityIdx) {
visited[cityIdx] = true;
for (int i = 0; i < isConnected.length; i++) {
// 标记与当前城市同省的其他城市
if (isConnected[cityIdx][i] ==1 && !visited[i]) {
dfs(visited, isConnected, i);
}
}
}
}
leetcode417
分析
统计网格流向2个大洋比较复杂。可以反过来,统计2个大洋逆流而上能够到达的网格。2个大洋都能逆流到达的网格就是能够流向大洋的。
源码
class Solution {
int[][] directions = {{1,0}, {-1,0},{0,1}, {0,-1}};
public List<List<Integer>> pacificAtlantic(int[][] heights) {
int m = heights.length;
int n = heights[0].length;
boolean[][] pacific = new boolean[m][n]; // 太平洋逆流而上能够到达的网格
boolean[][] atlantic = new boolean[m][n]; // 大西洋逆流而上能够到达的网格
for (int i = 0; i < m; i++) {
dfs(pacific, heights, i, 0);
dfs(atlantic, heights, i, n - 1);
}
for (int j = 0; j < n; j++) {
dfs(pacific, heights, 0, j);
dfs(atlantic, heights, m - 1, j);
}
// 对于heights[0][0],pacific会重复访问1次。对于heights[m-1][n-1],atlantic会重复访问1次。
List<List<Integer>> res = new ArrayList<>();
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (pacific[i][j] && atlantic[i][j]) {
res.add(List.of(i, j));
}
}
}
return res;
}
private void dfs(boolean[][] ocean, int[][] heights, int curI, int curJ) {
if (ocean[curI][curJ]) {
return;
}
ocean[curI][curJ] = true;
for (int i = 0; i < 4; i++) {
int nextI = curI + directions[i][0];
int nextJ = curJ + directions[i][1];
if (nextI >= 0 && nextI < heights.length && nextJ >= 0 && nextJ < heights[0].length && heights[nextI][nextJ] >= heights[curI][curJ]) {
dfs(ocean, heights, nextI, nextJ);
}
}
}
}

2391

被折叠的 条评论
为什么被折叠?



