深度优先搜索
回溯算法其实就是深搜,只不过这里的深搜是侧重于在图上搜索,回溯大多是在树上搜索。
797.所有可能的路径
完成
代码
模板题
class Solution {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
// 搜索以node为根的图
public void dfs(int[][] graph, int node) {
if(node == graph.length-1){
res.add(new ArrayList<>(path));
return;
}
// 遍历和node直连的所有节点
for(int index = 0; index < graph[node].length; index++){
path.add(graph[node][index]);
dfs(graph, graph[node][index]);
path.removeLast();
}
}
public List<List<Integer>> allPathsSourceTarget(int[][] graph) {
path.add(0);
dfs(graph, 0);
return res;
}
}
广度优先搜索
二叉树的层序遍历其实就是广度优先搜索。广搜一般需要栈或队列的辅助,但不局限于栈和队列,数组也可以。
200. 岛屿数量
完成
思路
我的第一版代码在搜索过程中,只会搜索节点右边和下边的节点,这是不对的。应该搜索节点上下左右四个方向的节点,因为在搜索过程中,从哪个方向搜到该节点是未知的,比如"工"字形的岛屿,搜索时最下排的位置最先搜到中间的节点,此时要往两边扩散,而不是只管右边。
代码
class Solution {
boolean[][] visited;
int[][] move = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
public int numIslands(char[][] grid) {
visited = new boolean[grid.length][grid[0].length];
int res = 0;
// 找岛屿
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if(!visited[i][j]&&grid[i][j] == '1'){
bfs(grid, i, j);
res++;
}
}
}
return res;
}
// 广搜,把连通的陆地打上标记
public void bfs(char[][] grid, int y, int x){
Deque<int[]> queue = new LinkedList<>();
queue.offer(new int[]{y, x});
visited[y][x] = true;
while (!queue.isEmpty()) {
int[] node = queue.poll();
for (int i = 0; i < 4; i++) {
int nextx = node[1] + move[i][1];
int nexty = node[0] + move[i][0];
if(nextx < 0 || nexty >= grid.length || nexty < 0 || nextx >= grid[0].length) continue;
if(!visited[nexty][nextx] && grid[nexty][nextx] == '1') {
queue.offer(new int[]{nexty, nextx});
visited[nexty][nextx] = true; //只要加入队列就标记为访问
}
}
}
}
}