DFS

BFS

LeetCode

934. 最短的桥

二维数组中存在两座岛屿(1表示陆地,0表示水),现在可以将0翻转1,求使得两座岛屿连接起来需要翻转0的最小数目。

  1. class Node {
  2. int r;
  3. int c;
  4. public Node(int r, int c) {
  5. this.r = r;
  6. this.c = c;
  7. }
  8. }
  9. private int rows;
  10. private int cols;
  11. //上下左右
  12. private int[] dirR = {-1, 1, 0, 0};
  13. private int[] dirC = {0, 0, -1, 1};
  14. private Queue<Node> queue = new LinkedList();
  15. public int shortestBridge(int[][] A) {
  16. rows = A.length;
  17. cols = A[0].length;
  18. boolean isFindFirst = false;
  19. //第一座岛屿染色
  20. for (int i = 0; i < rows; i++) {
  21. for (int j = 0; j < cols; j++) {
  22. if (A[i][j] == 0) continue;
  23. dfs(A, i, j);
  24. isFindFirst = true;
  25. break;
  26. }
  27. if (isFindFirst) break;
  28. }
  29. // bfs扩散寻找第二座岛屿
  30. int step = 0;
  31. while (!queue.isEmpty()) {
  32. int size = queue.size();
  33. while (size-- > 0) {
  34. Node node = queue.poll();
  35. for (int i = 0; i < dirR.length; i++) {
  36. int nextR = node.r + dirR[i], nextC = node.c + dirC[i];
  37. if (!isInArea(nextR, nextC) || A[nextR][nextC] == 2) continue;
  38. if (A[nextR][nextC] == 1) return step;
  39. A[nextR][nextC] = 2;
  40. queue.offer(new Node(nextR, nextC));
  41. }
  42. }
  43. step++;
  44. }
  45. return step;
  46. }
  47. private boolean isInArea(int i, int j) {
  48. return i >= 0 && i < rows && j >= 0 && j < cols;
  49. }
  50. private void dfs(int[][] graph, int r, int c) {
  51. queue.offer(new Node(r, c));
  52. graph[r][c] = 2;
  53. for (int i = 0; i < dirR.length; i++) {
  54. int nextR = r + dirR[i], nextC = c + dirC[i];
  55. if (!isInArea(nextR, nextC) || graph[nextR][nextC] != 1) continue;
  56. dfs(graph, nextR, nextC);
  57. }
  58. }

首先找到第一座岛(dfs),然后从第一座岛屿开始扩散到第二座岛屿(bfs)。