什么时候需要分层遍历?
什么时候不用分层遍历?
有时候刷题看解答就会疑惑,为什么在广度优先遍历的时候有的题解答中类似以下代码:
while (!queue.isEmpty()) {
int queueSize = queue.size();
for (int i = 0; i < queueSize; i++) {
int[] node = queue.poll();
int curNodeValue = matrix[node[0]][node[1]];
if (curValue == 0) {
// 到达目的地
return Cnt;
}
for (int[] moveStep : moveSteps) {
int newRow = node[0] + moveStep[0];
int newCol = node[1] + moveStep[1];
if (newRow < 0 || newRow >= rowNum || newCol < 0 || newCol >= colNum) {
// 超过matrix范围了
continue;
}
int[] newNode = new int[]{newRow, newCol};
if (matrix[newRow][newCol] == -1) {
// 遇到障碍物,跳过这个点
continue;
}
if (visited[newRow][newCol] == 0) {
// 还没有访问过的node
queue.offer(newNode);
visited[newRow][newCol] = 1;
}
}
}
// 为什么在这里++
cnt++;
}
这是因为这里在做层次遍历,就是说辐射是一层一层括出去的,先遍历完这一层,再去下一层
不仅要一个一个遍历,在遍历的时候还要有同层关系,遍历完这层,才算完成一步,cnt才能++。
又比如计算岛屿数量这个题,因为最终只需要求整个矩阵里有多少岛屿,没有层次遍历,只需要一层while循环即可:
class Solution {
private int count = 0;
private int[][] moveSteps = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
public int numIslands(char[][] grid) {
if (grid.length == 0 || grid[0].length == 0) {
return 0;
}
int row = grid.length;
int col = grid[0].length;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (grid[i][j] == '1') {
count++;
grid[i][j] = '0';
bfs(grid, i, j);
}
}
}
return count;
}
private void bfs(char[][] grid, int row, int col) {
Queue<int[]> queue = new LinkedList<>();
queue.add(new int[]{row, col});
while (!queue.isEmpty()) {
int[] node = queue.poll();
for (int[] moveStep : moveSteps) {
int newRow = node[0] + moveStep[0];
int newCol = node[1] + moveStep[1];
if (newRow < 0 || newRow >= grid.length
|| newCol < 0 || newCol >= grid[0].length) {
continue;
}
if (grid[newRow][newCol] == '1') {
queue.add(new int[]{newRow, newCol});
grid[newRow][newCol] = '0';
}
}
}
}
}
本文探讨了何时选择分层遍历(如广度优先搜索)和何时仅需单层循环(如岛屿计数)。讲解了分层遍历在解决需要逐层扩展的问题时的优势,并通过例子对比了广度优先遍历在路径探索和计算岛屿数量中的应用。关键词:层次遍历、广度优先、岛屿数量、队列算法
3021

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



