注意深搜的两种写法,熟练掌握这两种写法 以及 知道区别在哪里,才算掌握的深搜。
https://www.programmercarl.com/kamacoder/0099.%E5%B2%9B%E5%B1%BF%E7%9A%84%E6%95%B0%E9%87%8F%E6%B7%B1%E6%90%9C.html
import java.util.Scanner;
public class Main {
public static int[][] dir ={{0,1},{1,0},{-1,0},{0,-1}};
public static void dfs(boolean[][] visited,int x,int y ,int [][]grid)
{
for (int i = 0; i < 4; i++) {
int nextX=x+dir[i][0];
int nextY=y+dir[i][1];
if(nextY<0||nextX<0||nextX>= grid.length||nextY>=grid[0].length)
continue;
if(!visited[nextX][nextY]&&grid[nextX][nextY]==1)
{
visited[nextX][nextY]=true;
dfs(visited,nextX,nextY,grid);
}
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int m= sc.nextInt();
int n = sc.nextInt();
int[][] grid = new int[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
grid[i][j]=sc.nextInt();
}
}
boolean[][]visited =new boolean[m][n];
int ans = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if(!visited[i][j]&&grid[i][j]==1)
{
ans++;
visited[i][j]=true;
dfs(visited,i,j,grid);
}
}
}
System.out.println(ans);
}
}
注意广搜的两种写法,第一种写法为什么会超时, 如果自己做的录友,题目通过了,也要仔细看第一种写法的超时版本,弄清楚为什么会超时,因为你第一次 幸运 没那么想,第二次可就不一定了。
https://www.programmercarl.com/kamacoder/0099.%E5%B2%9B%E5%B1%BF%E7%9A%84%E6%95%B0%E9%87%8F%E5%B9%BF%E6%90%9C.html
import java.util.*;
public class Main {
public static int[][] dir = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};//下右上左逆时针遍历
public static void bfs(int[][] grid, boolean[][] visited, int x, int y) {
Queue queue = new LinkedList();//定义坐标队列,没有现成的pair类,在下面自定义了
queue.add(new pair(x, y));
visited[x][y] = true;//遇到入队直接标记为优先,
// 否则出队时才标记的话会导致重复访问,比如下方节点会在右下顺序的时候被第二次访问入队
while (!queue.isEmpty()) {
int curX = queue.peek().first;
int curY = queue.poll().second;//当前横纵坐标
for (int i = 0; i < 4; i++) {
//顺时针遍历新节点next,下面记录坐标
int nextX = curX + dir[i][0];
int nextY = curY + dir[i][1];
if (nextX < 0 || nextX >= grid.length || nextY < 0 || nextY >= grid[0].length) {
continue;
}//去除越界部分
if (!visited[nextX][nextY] && grid[nextX][nextY] == 1) {
queue.add(new pair(nextX, nextY));
visited[nextX][nextY] = true;//逻辑同上
}
}
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int m = sc.nextInt();
int n = sc.nextInt();
int[][] grid = new int[m][n];
boolean[][] visited = new boolean[m][n];
int ans = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
grid[i][j] = sc.nextInt();
}
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (!visited[i][j] && grid[i][j] == 1) {
ans++;
bfs(grid, visited, i, j);
}
}
}
System.out.println(ans);
}
}
本题就是基础题了,做过上面的题目,本题很快。
https://www.programmercarl.com/kamacoder/0100.%E5%B2%9B%E5%B1%BF%E7%9A%84%E6%9C%80%E5%A4%A7%E9%9D%A2%E7%A7%AF.html
# 四个方向
position = [[0, 1], [1, 0], [0, -1], [-1, 0]]
count = 0
def dfs(grid, visited, x, y):
"""
深度优先搜索,对一整块陆地进行标记
"""
global count # 定义全局变量,便于传递count值
for i, j in position:
cur_x = x + i
cur_y = y + j
# 下标越界,跳过
if cur_x < 0 or cur_x >= len(grid) or cur_y < 0 or cur_y >= len(grid[0]):
continue
if not visited[cur_x][cur_y] and grid[cur_x][cur_y] == 1:
visited[cur_x][cur_y] = True
count += 1
dfs(grid, visited, cur_x, cur_y)
n, m = map(int, input().split())
# 邻接矩阵
grid = []
for i in range(n):
grid.append(list(map(int, input().split())))
# 访问表
visited = [[False] * m for _ in range(n)]
result = 0 # 记录最终结果
for i in range(n):
for j in range(m):
if grid[i][j] == 1 and not visited[i][j]:
count = 1
visited[i][j] = True
dfs(grid, visited, i, j)
result = max(count, result)
print(result)