岛屿数量
深搜
注意深搜的两种写法,熟练掌握这两种写法 以及 知道区别在哪里,才算掌握的深搜。
import java.util.Scanner;
import java.util.Vector;
public class Main {
private static final int[][] dir = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};
public static void dfs(Vector<Vector<Integer>> grid, Vector<Vector<Boolean>> visited, int x, int y) {
for (int i = 0; i < 4; i++) {
int nextX = x + dir[i][0];
int nextY = y + dir[i][1];
// 检查是否越界
if (nextX < 0 || nextX >= grid.size() || nextY < 0 || nextY >= grid.get(0).size()) {
continue;
}
// 检查是否访问过且是陆地
if (!visited.get(nextX).get(nextY) && grid.get(nextX).get(nextY) == 1) {
visited.get(nextX).set(nextY, true);
dfs(grid, visited, nextX, nextY);
}
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int m = scanner.nextInt();
Vector<Vector<Integer>> grid = new Vector<>();
for (int i = 0; i < n; i++) {
Vector<Integer> row = new Vector<>();
for (int j = 0; j < m; j++) {
row.add(scanner.nextInt());
}
grid.add(row);
}
Vector<Vector<Boolean>> visited = new Vector<>();
for (int i = 0; i < n; i++) {
visited.add(new Vector<>(Collections.nCopies(m, false)));
}
int result = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (!visited.get(i).get(j) && grid.get(i).get(j) == 1) {
visited.get(i).set(j, true);
result++; // 遇到没访问过的陆地,+1
dfs(grid, visited, i, j); // 将与其链接的陆地都标记上 true
}
}
}
System.out.println(result);
scanner.close();
}
}
岛屿数量 广搜
注意广搜的两种写法,第一种写法为什么会超时, 如果自己做的录友,题目通过了,也要仔细看第一种写法的超时版本,弄清楚为什么会超时,因为你第一次 幸运 没那么想,第二次可就不一定了。
import java.util.Scanner;
import java.util.LinkedList;
import java.util.Queue;
public class Main {
private static final int[][] dir = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};
public static void bfs(int[][] grid, boolean[][] visited, int x, int y) {
Queue<int[]> que = new LinkedList<>();
que.offer(new int[]{x, y});
visited[x][y] = true; // 只要加入队列,立刻标记
while (!que.isEmpty()) {
int[] cur = que.poll();
int curx = cur[0];
int cury = cur[1];
for (int i = 0; i < 4; i++) {
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) {
que.offer(new int[]{nextx, nexty});
visited[nextx][nexty] = true; // 只要加入队列立刻标记
}
}
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int m = scanner.nextInt();
int[][] grid = new int[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
grid[i][j] = scanner.nextInt();
}
}
boolean[][] visited = new boolean[n][m];
int result = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (!visited[i][j] && grid[i][j] == 1) {
result++; // 遇到没访问过的陆地,+1
bfs(grid, visited, i, j); // 将与其链接的陆地都标记上 true
}
}
}
System.out.println(result);
scanner.close();
}
}
岛屿的最大面积
本题就是基础题了,做过上面的题目,本题很快。
import java.util.Scanner;
import java.util.Vector;
public class Main {
// 定义四个方向
private static final int[][] dir = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};
// 深度优先搜索函数
public static void dfs(Vector<Vector<Integer>> grid, Vector<Vector<Boolean>> visited, int x, int y, int[] count) {
for (int i = 0; i < 4; i++) {
int nextX = x + dir[i][0];
int nextY = y + dir[i][1];
// 检查是否越界
if (nextX < 0 || nextX >= grid.size() || nextY < 0 || nextY >= grid.get(0).size()) {
continue;
}
// 检查是否访问过且是陆地
if (!visited.get(nextX).get(nextY) && grid.get(nextX).get(nextY) == 1) {
visited.get(nextX).set(nextY, true);
count[0]++;
dfs(grid, visited, nextX, nextY, count);
}
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int m = scanner.nextInt();
Vector<Vector<Integer>> grid = new Vector<>();
for (int i = 0; i < n; i++) {
Vector<Integer> row = new Vector<>();
for (int j = 0; j < m; j++) {
row.add(scanner.nextInt());
}
grid.add(row);
}
Vector<Vector<Boolean>> visited = new Vector<>();
for (int i = 0; i < n; i++) {
visited.add(new Vector<>(Collections.nCopies(m, false)));
}
int result = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (!visited.get(i).get(j) && grid.get(i).get(j) == 1) {
int[] count = new int[1]; // 因为dfs需要修改count的值,所以使用数组
visited.get(i).set(j, true);
dfs(grid, visited, i, j, count); // 将与其链接的陆地都标记上 true
result = Math.max(result, count[0]);
}
}
}
System.out.println(result);
scanner.close();
}
}