BFS
宽度优先搜索
计算疫情扩散时间
感染区就相当于我们往水面扔了一颗石子,广度优先搜索就相当于荡起的一圈涟漪
而二叉树的 BFS 是只会向左右2侧泛起涟漪!!!
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
static boolean[][] isVisited;
static Deque<Integer[]> deque = new ArrayDeque<>();
static int N;
static int[][] arr;
static int res;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String[] str = in.nextLine().split(",");
N = str.length;
int count = (int) Math.pow(N, 0.5);
isVisited = new boolean[count][count];
arr = new int[count][count];
int index = 0;
int startWeak = 0;
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length; j++) {
arr[i][j] = Integer.parseInt(str[index++]);
if (arr[i][j] == 1){
isVisited[i][j] = true;
deque.offer(new Integer[]{i, j});
startWeak++;
}
}
}
if (startWeak == 0 || startWeak == N){
System.out.println(-1);
return;
}
bfs();
System.out.println(res - 1);
}
public static void bfs(){
while (!deque.isEmpty()) {
int size = deque.size();
while (size > 0) {
Integer[] peek = deque.poll();
turnWeak(peek[0], peek[1]);
size--;
}
res++;
}
}
public static void turnWeak(int i, int j){
if (i - 1 >= 0 && !isVisited[i - 1][j]){ // 上
deque.offer(new Integer[]{i - 1, j});
isVisited[i - 1][j] = true;
}
if (i + 1 < Math.sqrt(N) && !isVisited[i + 1][j]){ // 下
deque.offer(new Integer[]{i + 1, j} );
isVisited[i + 1][j] = true;
}
if (j - 1 >= 0 && !isVisited[i][j - 1]){ // 左
deque.offer(new Integer[]{i, j - 1} );
isVisited[i][j - 1] = true;
}
if (j + 1 < Math.sqrt(N) && !isVisited[i][j + 1]){
deque.offer(new Integer[]{i, j + 1} );
isVisited[i][j + 1] = true;
}
}
}
寻找最大价值的矿堆
注意:与二叉树的类比
二叉树队列添加的前提条件:peek.left 或者 peek.right 不为 null
而到了图中:则变为
- 符合条件的
- 之前没有访问过的
注意在添加后,要将该点的状态更改为已访问
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
static boolean[][] isVisited;
static int row;
static int col;
static int[][] arr;
static int res;
static Deque<Integer[]> deque = new ArrayDeque<>();
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
StringBuilder sb = new StringBuilder();
while (in.hasNextLine()) {
String s = in.nextLine();
if ("".equals(s)) {
break;
}
sb.append(s + " ");
}
String str = sb.toString().trim();
String[] split = str.split(" ");
row = split.length;
col = split[0].length();
isVisited = new boolean[row][col];
arr = new int[row][col];
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
arr[i][j] = split[i].charAt(j) - '0';
}
}
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (arr[i][j] > 0 && !isVisited[i][j]){
isVisited[i][j] = true;
deque.offer(new Integer[]{i, j});
res = Math.max(res, bfs());
}
}
}
System.out.println(res);
}
public static int bfs() {
int sum = 0;
while (!deque.isEmpty()) {
int size = deque.size();
while (size > 0) {
Integer[] peek = deque.poll();
sum += arr[peek[0]][peek[1]];
getNearBy(peek[0], peek[1]);
size--;
}
}
return sum;
}
public static void getNearBy(int i, int j) {
if (i - 1 >= 0 && arr[i - 1][j] > 0 && !isVisited[i - 1][j]) { // 上
isVisited[i - 1][j] = true;
deque.offer(new Integer[]{i - 1, j});
}
if (i + 1 < row && arr[i + 1][j] > 0 && !isVisited[i + 1][j]) { // 下
isVisited[i + 1][j] = true;
deque.offer(new Integer[]{i + 1, j});
}
if (j - 1 >= 0 && arr[i][j - 1] > 0 && !isVisited[i][j - 1]) { // 左
isVisited[i][j - 1] = true;
deque.offer(new Integer[]{i, j - 1});
}
if (j + 1 < col && arr[i][j + 1] > 0 && !isVisited[i][j + 1]) { // 右
isVisited[i][j + 1] = true;
deque.offer(new Integer[]{i, j + 1});
}
}
}
可以组成网络的服务器【类似矿堆】
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
static int row;
static int col;
static boolean[][] isVisited;
static int[][] arr;
static Deque<Integer[]> deque = new ArrayDeque<>();
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String[] split = in.nextLine().split(" ");
row = Integer.parseInt(split[0]);
col = Integer.parseInt(split[1]);
isVisited = new boolean[row][col];
arr = new int[row][col];
StringBuilder sb = new StringBuilder();
for (int i = 0; i < row; i++) {
sb.append(in.nextLine() + " ");
}
String[] temp = sb.toString().trim().split(" ");
int index = 0;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
arr[i][j] = Integer.parseInt(temp[index++]);
}
}
int res = 0;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (arr[i][j] > 0){
deque.offer(new Integer[]{i, j});
isVisited[i][j] = true;
res = Math.max(res, bfs());
}
}
}
System.out.println(res);
}
public static int bfs(){
int sum = 0;
while (!deque.isEmpty()){
int size = deque.size();
while (size > 0){
Integer[] peek = deque.poll();
sum += arr[peek[0]][peek[1]];
getRowCount(peek[0], peek[1]);
size--;
}
}
return sum;
}
public static void getRowCount(int i, int j){
if (i - 1 >= 0 && !isVisited[i - 1][j] && arr[i - 1][j] > 0){
deque.offer(new Integer[]{i - 1, j});
isVisited[i - 1][j] = true;
}
if (i + 1 < row && !isVisited[i + 1][j] && arr[i + 1][j] > 0){
deque.offer(new Integer[]{i + 1, j});
isVisited[i + 1][j] = true;
}
if(j - 1 >= 0 && !isVisited[i][j - 1] && arr[i][j - 1] > 0){
deque.offer(new Integer[]{i, j - 1});
isVisited[i][j - 1] = true;
}
if (j + 1 < col && !isVisited[i][j + 1] && arr[i][j + 1] > 0){
deque.offer(new Integer[]{i, j + 1});
isVisited[i][j + 1] = true;
}
}
}
战场索敌
可以理解为:以2为边界,求0 和 1 的和,满足小于 K即可
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
static int[][] arr;
static Deque<Integer[]> deque = new ArrayDeque<>();
static boolean[][] isVisited;
static int N;
static int row;
static int col;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String[] split = in.nextLine().split(" ");
row = Integer.parseInt(split[0]);
col = Integer.parseInt(split[1]);
isVisited = new boolean[row][col];
N = Integer.parseInt(split[2]);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < row; i++) {
String str = in.nextLine().replace(".", "0").replace("#", "2").replace("E", "1");
sb.append(str);
}
int index = 0;
String[] temp = sb.toString().split("");
arr = new int[row][col];
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
arr[i][j] = Integer.parseInt(temp[index++]);
}
}
int count = 0;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (arr[i][j] < 2 && !isVisited[i][j]){
deque.offer(new Integer[]{i, j});
isVisited[i][j] = true;
if (bfs() < N){
count++;
}
}
}
}
System.out.println(count);
}
public static int bfs(){
int sum = 0;
while (!deque.isEmpty()){
int size = deque.size();
while (size > 0){
Integer[] peek = deque.poll();
sum += arr[peek[0]][peek[1]];
addEnemy(peek[0], peek[1]);
size--;
}
}
return sum;
}
public static void addEnemy(int i, int j){
if (i - 1 >=0 && !isVisited[i - 1][j] && arr[i - 1][j] < 2){
deque.offer(new Integer[]{i - 1, j});
isVisited[i - 1][j] = true;
}
if (i + 1 < row && !isVisited[i + 1][j] && arr[i + 1][j] < 2){
deque.offer(new Integer[]{i + 1, j});
isVisited[i + 1][j] = true;
}
if (j - 1 >=0 && !isVisited[i][j - 1] && arr[i][j - 1] < 2){
deque.offer(new Integer[]{i, j - 1});
isVisited[i][j - 1] = true;
}
if (j + 1 < col && !isVisited[i][j + 1] && arr[i][j + 1] < 2){
deque.offer(new Integer[]{i, j + 1});
isVisited[i][j + 1] = true;
}
}
}
宜居星球改造计划【扩散问题,开始要把符合的都先入队】
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
static int row;
static int col;
static Deque<Integer[]> deque = new ArrayDeque<>();
static boolean[][] isVisited;
static int[][] arr;
static int badCount;
static int day;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
StringBuilder sb = new StringBuilder();
while (in.hasNextLine()){
String s = in.nextLine();
if ("".equals(s)){
break;
}
sb.append(s + ",");
row++;
}
String str = sb.toString().substring(0, sb.length() - 1).replace("YES", "0").replace("NO", "1").replace("NA", "2");
col = str.split(",")[0].replace(" ", "").length();
String[] split = str.split("[ ,]");
isVisited = new boolean[row][col];
int index = 0;
arr = new int[row][col];
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
arr[i][j] = Integer.parseInt(split[index++]);
if (arr[i][j] == 1){
badCount++;
}
}
}
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (arr[i][j] == 0 && !isVisited[i][j]){ // 扩散问题:开始就将符合的都放到 队列中
deque.offer(new Integer[]{i, j});
isVisited[i][j] = true;
}
}
}
bfs();
if (badCount != 0){
System.out.println(-1);
return;
}
System.out.println(day - 1);
}
public static void bfs(){
while (!deque.isEmpty()){
int size = deque.size();
while (size > 0){
Integer[] peek = deque.poll();
addSpace(peek[0], peek[1]);
size--;
}
day++;
}
}
public static void addSpace(int i, int j){
if (i - 1 >=0 && !isVisited[i - 1][j] && arr[i - 1][j] == 1){
arr[i - 1][j] = 0;
deque.offer(new Integer[]{i - 1, j});
isVisited[i - 1][j] = true;
badCount--;
}
if (i + 1 < row && !isVisited[i + 1][j] && arr[i + 1][j] == 1){
arr[i + 1][j] = 0;
deque.offer(new Integer[]{i + 1, j});
isVisited[i + 1][j] = true;
badCount--;
}
if (j - 1 >=0 && !isVisited[i][j - 1] && arr[i][j - 1] == 1){
arr[i][j - 1] = 0;
deque.offer(new Integer[]{i, j - 1});
isVisited[i][j - 1] = true;
badCount--;
}
if (j + 1 < col && !isVisited[i][j + 1] && arr[i][j + 1] == 1){
arr[i][j + 1] = 0;
deque.offer(new Integer[]{i, j + 1});
isVisited[i][j + 1] = true;
badCount--;
}
}
}
周末爬山
问题:
请问小明能爬到的最高峰多高,到该最高峰的最短步数,输出以空格分隔
- 最高
- 最短
难点:
- 何时到达能到达的最高处
- 到达整个数组的最大值
- 到达能走到的最大值【未知,难道要遍历2次??】===> 遍历2次可以通过用例【在第二次遍历开始前,注意把 isVisited 重置为 false】
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
static int row;
static int col;
static int k;
static int[][] arr;
static boolean[][] isVisited;
static int time = 0;
static int max = 0;
static Deque<Integer[]> deque = new ArrayDeque<>();
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String[] split = in.nextLine().split(" ");
row = Integer.parseInt(split[0]);
col = Integer.parseInt(split[1]);
isVisited = new boolean[row][col];
arr = new int[row][col];
k = Integer.parseInt(split[2]);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < row; i++) {
sb.append(in.nextLine() + " ");
}
String[] temp = sb.toString().trim().split(" ");
int index = 0;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
arr[i][j] = Integer.parseInt(temp[index++]);
}
}
deque.offer(new Integer[]{0, 0});
isVisited[0][0] = true;
bfs1();
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
isVisited[i][j] = false;
}
}
deque.offer(new Integer[]{0, 0});
isVisited[0][0] = true;
bfs2();
if (max == 0){
System.out.println("0" + " " + "0");
return;
}
System.out.println(max + " " + time);
}
public static void bfs1(){
while (!deque.isEmpty()){
int size = deque.size();
while (size > 0){ // 每层的
Integer[] peek = deque.poll();
max = Math.max(max, arr[peek[0]][peek[1]]);
getNearBy(peek[0], peek[1]);
size--;
}
}
}
public static void bfs2(){
while (!deque.isEmpty()){
int size = deque.size();
while (size > 0){ // 每层的
Integer[] peek = deque.poll();
if (arr[peek[0]][peek[1]] == max){
return;
}
getNearBy(peek[0], peek[1]);
size--;
}
time++;
}
}
public static void getNearBy(int i, int j){
int temp = arr[i][j];
if (i - 1 >= 0 && !isVisited[i - 1][j] && Math.abs(arr[i - 1][j] - temp) <= k){
isVisited[i - 1][j] = true;
deque.offer(new Integer[]{i - 1, j});
}
if (i + 1 < row && !isVisited[i + 1][j] && Math.abs(arr[i + 1][j] - temp) <= k){
isVisited[i + 1][j] = true;
deque.offer(new Integer[]{i + 1, j});
}
if (j - 1 >= 0 && !isVisited[i][j - 1] && Math.abs(arr[i][j - 1] - temp) <= k){
isVisited[i][j - 1] = true;
deque.offer(new Integer[]{i, j - 1});
}
if (j + 1 < col && !isVisited[i][j + 1] && Math.abs(arr[i][j + 1] - temp) <= k){
isVisited[i][j + 1] = true;
deque.offer(new Integer[]{i, j + 1});
}
}
}
返回矩阵中非1元素个数
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
static int row;
static int col;
static int[][] arr;
static boolean[][] isVisited;
static Deque<Integer[]> deque = new ArrayDeque<>();
static int sum;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String[] split = in.nextLine().split(" ");
row = Integer.parseInt(split[0]);
col = Integer.parseInt(split[1]);
arr = new int[row][col];
isVisited = new boolean[row][col];
StringBuilder sb = new StringBuilder();
for (int i = 0; i < row; i++) {
sb.append(in.nextLine() + " ");
}
int index = 0;
String[] temp = sb.toString().trim().split(" ");
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
arr[i][j] = Integer.parseInt(temp[index++]);
}
}
sum = row * col - 1;
arr[0][0] = 1;
isVisited[0][0] = true;
deque.offer(new Integer[]{0, 0});
bfs();
System.out.println(sum);
}
public static void bfs(){
while (!deque.isEmpty()){
int size = deque.size();
while (size > 0){
Integer[] peek = deque.poll();
turnWeak(peek[0], peek[1]);
size--;
}
}
}
public static void turnWeak(int i, int j){
if (i - 1 >= 0 && !isVisited[i - 1][j] && arr[i - 1][j] != 2){
isVisited[i - 1][j] = true;
deque.offer(new Integer[]{i - 1, j});
sum--;
}
if (i + 1 < row && !isVisited[i + 1][j] && arr[i + 1][j] != 2){
isVisited[i + 1][j] = true;
deque.offer(new Integer[]{i + 1, j});
sum--;
}
if (j - 1 >= 0 && !isVisited[i][j - 1] && arr[i][j - 1] != 2){
isVisited[i][j - 1] = true;
deque.offer(new Integer[]{i, j - 1});
sum--;
}
if (j + 1 < col && !isVisited[i][j + 1] && arr[i][j + 1] != 2){
isVisited[i][j + 1] = true;
deque.offer(new Integer[]{i, j + 1});
sum--;
}
}
}
欢乐的周末
难点:
- 2个点要连通
- 以其中一个2为起点,开始入队,引入变量count表示2的个数
- 如果最终count != 2,则说明不是连通的,输出0
- 否则bfs 求和即可
- 注意 row 和 col的顺序
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
static int row;
static int col;
static int[][] arr;
static boolean[][] isVisited;
static Deque<Integer[]> deque = new ArrayDeque<>();
static int count = 0;
static int res = 0;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String[] split = in.nextLine().split(" ");
col = Integer.parseInt(split[0]);
row = Integer.parseInt(split[1]);
arr = new int[row][col];
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
arr[i][j] = in.nextInt();
}
}
isVisited = new boolean[row][col];
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (arr[i][j] == 2 && count == 0){
deque.offer(new Integer[]{i, j});
isVisited[i][j] = true;
bfs();
}
}
}
if (count != 2){
System.out.println(0);
return;
}
System.out.println((res - 4) / 3);
}
public static void bfs(){
while (!deque.isEmpty()){
int size = deque.size();
while (size > 0){
Integer[] peek = deque.poll();
if (arr[peek[0]][peek[1]] == 2){
count++; // 如果最终弹不出2个 2的话,找不到!!!
}
res += arr[peek[0]][peek[1]];
getNearBy(peek[0], peek[1]);
size--;
}
}
}
public static void getNearBy(int i, int j){
while (i - 1 >= 0 && !isVisited[i- 1][j] && arr[i - 1][j] != 1){
isVisited[i - 1][j] = true;
deque.offer(new Integer[]{i - 1, j});
}
while (i + 1 < row && !isVisited[i + 1][j] && arr[i + 1][j] != 1){
isVisited[i + 1][j] = true;
deque.offer(new Integer[]{i + 1, j});
}
while (j - 1 >= 0 && !isVisited[i][j - 1] && arr[i][j - 1] != 1){
isVisited[i][j - 1] = true;
deque.offer(new Integer[]{i, j - 1});
}
while (j + 1 < col && !isVisited[i][j + 1] && arr[i][j + 1] != 1){
isVisited[i][j + 1] = true;
deque.offer(new Integer[]{i, j + 1});
}
}
}
力扣
200. 岛屿数量
注意字符间比大小,要用单引号 '1'
class Solution {
int sum = 0;
boolean[][] isVisited;
int row;
int col;
Deque<Integer[]> deque = new ArrayDeque<>();
public int numIslands(char[][] grid) {
row = grid.length;
col = grid[0].length;
isVisited = new boolean[row][col];
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (grid[i][j] == '1' && !isVisited[i][j]){
isVisited[i][j] = true;
deque.offer(new Integer[]{i, j});
sum++;
bfs(grid);
}
}
}
return sum;
}
public void bfs(char[][] grid){
while (!deque.isEmpty()){
int size = deque.size();
while (size > 0){
Integer[] peek = deque.poll();
getNearBy(peek[0], peek[1], grid);
size--;
}
}
}
public void getNearBy(int i, int j, char[][] chars){
if (i - 1 >= 0 && !isVisited[i - 1][j] && chars[i - 1][j] == '1'){
isVisited[i - 1][j] = true;
deque.offer(new Integer[]{i - 1, j});
}
if (i + 1 < row && !isVisited[i + 1][j] && chars[i + 1][j] == '1'){
isVisited[i + 1][j] = true;
deque.offer(new Integer[]{i + 1, j});
}
if (j - 1 >= 0 && !isVisited[i][j - 1] && chars[i][j - 1] == '1'){
isVisited[i][j - 1] = true;
deque.offer(new Integer[]{i, j - 1});
}
if (j + 1 < col && !isVisited[i][j + 1] && chars[i][j + 1] == '1'){
isVisited[i][j + 1] = true;
deque.offer(new Integer[]{i, j + 1});
}
}
}
695. 岛屿的最大面积
class Solution {
int res = 0;
boolean[][] isVisited;
int row;
int col;
Deque<Integer[]> deque = new ArrayDeque<>();
public int maxAreaOfIsland(int[][] grid) {
row = grid.length;
col = grid[0].length;
isVisited = new boolean[row][col];
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (grid[i][j] == 1 && !isVisited[i][j]){
isVisited[i][j] = true;
deque.offer(new Integer[]{i, j});
res = Math.max(res, bfs(grid));
}
}
}
return res;
}
public int bfs(int[][] grid){
int sum = 0;
while (!deque.isEmpty()){
int size = deque.size();
while (size > 0){
Integer[] peek = deque.poll();
sum++;
getNearBy(peek[0], peek[1], grid);
size--;
}
}
return sum;
}
public void getNearBy(int i, int j, int[][] chars){
if (i - 1 >= 0 && !isVisited[i - 1][j] && chars[i - 1][j] == 1){
isVisited[i - 1][j] = true;
deque.offer(new Integer[]{i - 1, j});
}
if (i + 1 < row && !isVisited[i + 1][j] && chars[i + 1][j] == 1){
isVisited[i + 1][j] = true;
deque.offer(new Integer[]{i + 1, j});
}
if (j - 1 >= 0 && !isVisited[i][j - 1] && chars[i][j - 1] == 1){
isVisited[i][j - 1] = true;
deque.offer(new Integer[]{i, j - 1});
}
if (j + 1 < col && !isVisited[i][j + 1] && chars[i][j + 1] == 1){
isVisited[i][j + 1] = true;
deque.offer(new Integer[]{i, j + 1});
}
}
}
130. 被围绕的区域
找到边界的 'O',开始扩散,并标记为访问过,最后再将所有为标记过的 'O',改为 'X'
class Solution {
int row;
int col;
boolean[][] isVisited;
Deque<Integer[]> deque = new ArrayDeque<>();
public void solve(char[][] board) {
// https://leetcode.cn/problems/surrounded-regions/solutions/2213619/bao-li-sou-suo-suo-you-yu-bian-jie-shang-bz3f/
row = board.length;
col = board[0].length;
isVisited = new boolean[row][col];
// 找到边界的 O 然后扩散!!!
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (i == 0 || i == row - 1 || j == 0 || j == col - 1) {
if (board[i][j] == 'O') {
deque.offer(new Integer[]{i, j});
isVisited[i][j] = true;
}
}
}
}
bfs(board);
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (board[i][j] == 'O' && !isVisited[i][j]){ // 最后未被添加过的 'O' 重置为:'X'
board[i][j] = 'X';
}
}
}
}
public void bfs(char[][] grid){
while (!deque.isEmpty()){
int size = deque.size();
while (size > 0){
Integer[] peek = deque.poll(); // 弹出的所有都是不被包围的!!!
getNearBy(peek[0], peek[1], grid);
size--;
}
}
}
public void getNearBy(int i, int j, char[][] chars){
if (i - 1 >= 0 && !isVisited[i - 1][j] && chars[i - 1][j] == 'O'){
isVisited[i - 1][j] = true;
deque.offer(new Integer[]{i - 1, j});
}
if (i + 1 < row && !isVisited[i + 1][j] && chars[i + 1][j] == 'O'){
isVisited[i + 1][j] = true;
deque.offer(new Integer[]{i + 1, j});
}
if (j - 1 >= 0 && !isVisited[i][j - 1] && chars[i][j - 1] == 'O'){
isVisited[i][j - 1] = true;
deque.offer(new Integer[]{i, j - 1});
}
if (j + 1 < col && !isVisited[i][j + 1] && chars[i][j + 1] == 'O'){
isVisited[i][j + 1] = true;
deque.offer(new Integer[]{i, j + 1});
}
}
}
1254. 统计封闭岛屿的数目【和上题类似】
要求的区域 = 0构成的所有区域 - 边界0的区域
class Solution {
int res = 0;
int count = 0;
boolean[][] isVisited;
int row;
int col;
Deque<Integer[]> deque = new ArrayDeque<>();
public int closedIsland(int[][] grid) {
row = grid.length;
col = grid[0].length;
isVisited = new boolean[row][col];
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (grid[i][j] == 0 && !isVisited[i][j]) {
count++;
deque.offer(new Integer[]{i, j});
isVisited[i][j] = true;
bfs(grid);
}
}
}
for (int i = 0; i < row; i++) {
Arrays.fill(isVisited[i], false);
}
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (i == 0 || i == row - 1 || j == 0 || j == col - 1){
if (grid[i][j] == 0 && !isVisited[i][j]){
deque.offer(new Integer[]{i, j});
isVisited[i][j] = true;
res++;
bfs(grid);
}
}
}
}
return count - res;
}
public void bfs(int[][] grid){
while (!deque.isEmpty()){
int size = deque.size();
while (size > 0){
Integer[] peek = deque.poll();
getNearBy(peek[0], peek[1], grid);
size--;
}
}
}
public void getNearBy(int i, int j, int[][] chars){
if (i - 1 >= 0 && !isVisited[i - 1][j] && chars[i - 1][j] == 0){
isVisited[i - 1][j] = true;
deque.offer(new Integer[]{i - 1, j});
}
if (i + 1 < row && !isVisited[i + 1][j] && chars[i + 1][j] == 0){
isVisited[i + 1][j] = true;
deque.offer(new Integer[]{i + 1, j});
}
if (j - 1 >= 0 && !isVisited[i][j - 1] && chars[i][j - 1] == 0){
isVisited[i][j - 1] = true;
deque.offer(new Integer[]{i, j - 1});
}
if (j + 1 < col && !isVisited[i][j + 1] && chars[i][j + 1] == 0){
isVisited[i][j + 1] = true;
deque.offer(new Integer[]{i, j + 1});
}
}
}
994. 腐烂的橘子
class Solution {
boolean[][] isVisited;
int row;
int col;
int goodCount;
int day;
Deque<Integer[]> deque = new ArrayDeque<>();
public int orangesRotting(int[][] grid) {
row = grid.length;
col = grid[0].length;
isVisited = new boolean[row][col];
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (grid[i][j] == 1){
goodCount++;
}
if (grid[i][j] == 2){
deque.offer(new Integer[]{i, j});
}
}
}
if (goodCount == 0){ // 如果一开始就没有好橘子了,返回 0天
return 0;
}
bfs(grid);
if (goodCount > 0){ // 有憋在死角的橘子,返回 - 1
return -1;
}
return day - 1; // 可以全部腐蚀,减去初始的那一天 day0
}
public void bfs(int[][] arr){
while (!deque.isEmpty()){
int len = deque.size();
while (len > 0){
Integer[] peek = deque.poll();
goRound(arr, peek[0], peek[1]);
len--;
}
day++;
}
}
public void goRound(int[][] arr, int i, int j){
if (i - 1 >= 0 && !isVisited[i - 1][j] && arr[i - 1][j] == 1){
isVisited[i - 1][j] = true;
goodCount--;
deque.add(new Integer[]{i - 1, j});
}
if (i + 1 < row && !isVisited[i + 1][j] && arr[i + 1][j] == 1){
isVisited[i + 1][j] = true;
goodCount--;
deque.add(new Integer[]{i + 1, j});
}
if (j - 1 >= 0 && !isVisited[i][j - 1] && arr[i][j - 1] == 1){
isVisited[i][j - 1] = true;
goodCount--;
deque.add(new Integer[]{i, j - 1});
}
if (j + 1 < col && !isVisited[i][j + 1] && arr[i][j + 1] == 1){
isVisited[i][j + 1] = true;
goodCount--;
deque.add(new Integer[]{i, j + 1});
}
}
}
矩阵扩散
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
static int[][] offsets = {{1, 0}, {0, -1}, {-1, 0}, {0, 1}};
static boolean[][] isVisited;
static Deque<Integer[]> deque = new ArrayDeque<>();
static int[][] arr;
static int row;
static int col;
static int day;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String[] split = in.nextLine().split(",");
row = Integer.parseInt(split[0]);
col = Integer.parseInt(split[1]);
arr = new int[row][col];
int x1 = Integer.parseInt(split[2]);
int y1 = Integer.parseInt(split[3]);
int x2 = Integer.parseInt(split[4]);
int y2 = Integer.parseInt(split[5]);
isVisited = new boolean[row][col];
isVisited[x1][y1] = true;
isVisited[x2][y2] = true;
deque.offer(new Integer[]{x1, y1});
deque.offer(new Integer[]{x2, y2});
bfs();
System.out.println(day - 1);
}
public static void bfs(){
while (!deque.isEmpty()){
int len = deque.size();
while (len > 0){
Integer[] peek = deque.poll();
goRound(peek[0], peek[1]);
len--;
}
day++;
}
}
public static void goRound(int i, int j){
for (int[] offset : offsets) {
int x = i + offset[0];
int y = j + offset[1];
if (x >= 0 && x < row && y >= 0 && y < col && !isVisited[x][y] && arr[x][y] == 0){
deque.offer(new Integer[]{x, y});
isVisited[x][y] = true;
}
}
}
}
污染水域
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
static int[][] offsets = {{1, 0}, {0, -1}, {-1, 0}, {0, 1}};
static boolean[][] isVisited;
static Deque<Integer[]> deque = new ArrayDeque<>();
static int[][] arr;
static int N;
static int day;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String[] split = in.nextLine().split(",");
int len = split.length;
N = (int)Math.sqrt(len);
arr = new int[N][N];
isVisited = new boolean[N][N];
int index = 0;
int temp = 0;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
arr[i][j] = Integer.parseInt(split[index++]);
if (!isVisited[i][j] && arr[i][j] == 1){
temp++;
deque.offer(new Integer[]{i, j});
isVisited[i][j] = true;
}
}
}
if (temp == 0 || temp == len){
System.out.println(-1);
return;
}
bfs();
System.out.println(day - 1);
}
public static void bfs(){
while (!deque.isEmpty()){
int len = deque.size();
while (len > 0){
Integer[] peek = deque.poll();
goRound(peek[0], peek[1]);
len--;
}
day++;
}
}
public static void goRound(int i, int j){
for (int[] offset : offsets) {
int x = i + offset[0];
int y = j + offset[1];
if (x >= 0 && x < N && y >= 0 && y < N && !isVisited[x][y] && arr[x][y] == 0){
deque.offer(new Integer[]{x, y});
isVisited[x][y] = true;
}
}
}
}