• LeetCode —— dfs和bfs


    797. 所有可能的路径

    给你一个有 n 个节点的 有向无环图(DAG),请你找出所有从节点 0 到节点 n-1 的路径并输出(不要求按特定顺序)。 graph[i] 是一个从节点 i 可以访问的所有节点的列表(即从节点 i 到节点 graph[i][j]存在一条有向边)。

    示例1:输入:graph = [[1,2],[3],[3],[]]         输出:[[0,1,3],[0,2,3]] 

    示例2:输入:graph = [[4,3,1],[3,2,4],[3],[4],[]]      输出:[[0,4],[0,3,4],[0,1,3,4],[0,1,2,3,4],[0,1,4]]

    1. // dfs
    2. class Solution {
    3. List> list = new ArrayList<>();
    4. LinkedList path = new LinkedList<>();
    5. public List> allPathsSourceTarget(int[][] graph) {
    6. path.add(0);
    7. dfs(graph, 0);
    8. return list;
    9. }
    10. public void dfs(int[][] graph, int node){
    11. if(node == graph.length - 1){
    12. list.add(new ArrayList<>(path));
    13. return;
    14. }
    15. for(int i = 0; i < graph[node].length; i++){
    16. path.add(graph[node][i]);
    17. dfs(graph, graph[node][i]);
    18. path.removeLast();
    19. }
    20. }
    21. }

    200. 岛屿数量

    给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。此外,你可以假设该网格的四条边均被水包围。

    示例1:

    输入:grid = [
      ["1","1","1","1","0"],
      ["1","1","0","1","0"],
      ["1","1","0","0","0"],
      ["0","0","0","0","0"]
    ]
    输出:1
    
    1. // dfs (以下三种方式等价)
    2. class Solution {
    3. public int numIslands(char[][] grid) {
    4. int count = 0;
    5. for(int i = 0; i < grid.length; i++){
    6. for(int j = 0; j < grid[0].length; j++){
    7. if(grid[i][j] == '1'){
    8. count++;
    9. dfs(grid, i, j);
    10. }
    11. }
    12. }
    13. return count;
    14. }
    15. public void dfs(char[][] grid, int i, int j){
    16. if(i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == '0'){
    17. return;
    18. }
    19. grid[i][j] = '0';
    20. dfs(grid, i - 1, j);
    21. dfs(grid, i + 1, j);
    22. dfs(grid, i, j - 1);
    23. dfs(grid, i, j + 1);
    24. }
    25. }
    26. class Solution {
    27. int[][] positions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    28. public int numIslands(char[][] grid) {
    29. int count = 0;
    30. for(int i = 0; i < grid.length; i++){
    31. for(int j = 0; j < grid[0].length; j++){
    32. if(grid[i][j] == '1'){
    33. count++;
    34. dfs(grid, i, j);
    35. }
    36. }
    37. }
    38. return count;
    39. }
    40. public void dfs(char[][] grid, int i, int j){
    41. if(i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == '0'){
    42. return;
    43. }
    44. grid[i][j] = '0';
    45. for(int[] pos : positions){
    46. int newRow = i + pos[0];
    47. int newColumn = j + pos[1];
    48. dfs(grid, newRow, newColumn);
    49. }
    50. }
    51. }
    52. class Solution {
    53. int[][] positions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    54. boolean[][] visited; // 通过判断该位置是否被访问过,而不是将1修改为0
    55. public int numIslands(char[][] grid) {
    56. visited = new boolean[grid.length][grid[0].length];
    57. int count = 0;
    58. for(int i = 0; i < grid.length; i++){
    59. for(int j = 0; j < grid[0].length; j++){
    60. if(grid[i][j] == '1' && !visited[i][j]){
    61. count++;
    62. dfs(grid, i, j);
    63. }
    64. }
    65. }
    66. return count;
    67. }
    68. public void dfs(char[][] grid, int i, int j){
    69. if(i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || visited[i][j] || grid[i][j] == '0'){
    70. return;
    71. }
    72. visited[i][j] = true;
    73. for(int[] pos : positions){
    74. int newRow = i + pos[0];
    75. int newColumn = j + pos[1];
    76. dfs(grid, newRow, newColumn);
    77. }
    78. }
    79. }
    1. // bfs 以下三种方式等价
    2. class Solution {
    3. public int numIslands(char[][] grid) {
    4. int count = 0;
    5. for(int i = 0; i < grid.length; i++){
    6. for(int j = 0; j < grid[0].length; j++){
    7. if(grid[i][j] == '1'){
    8. count++;
    9. bfs(grid, i, j);
    10. }
    11. }
    12. }
    13. return count;
    14. }
    15. public void bfs(char[][] grid, int i, int j){
    16. Queue<int[]> queue = new LinkedList<>();
    17. queue.offer(new int[]{i, j});
    18. while(!queue.isEmpty()){
    19. int[] cur = queue.poll();
    20. i = cur[0];
    21. j = cur[1];
    22. if(i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == '0'){
    23. continue;
    24. }
    25. grid[i][j] = '0';
    26. queue.offer(new int[]{i - 1, j});
    27. queue.offer(new int[]{i + 1, j});
    28. queue.offer(new int[]{i, j - 1});
    29. queue.offer(new int[]{i, j + 1});
    30. }
    31. }
    32. }
    33. class Solution {
    34. int[][] positions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    35. public int numIslands(char[][] grid) {
    36. int count = 0;
    37. for(int i = 0; i < grid.length; i++){
    38. for(int j = 0; j < grid[0].length; j++){
    39. if(grid[i][j] == '1'){
    40. count++;
    41. bfs(grid, i, j);
    42. }
    43. }
    44. }
    45. return count;
    46. }
    47. public void bfs(char[][] grid, int i, int j){
    48. Queue<int[]> queue = new LinkedList();
    49. queue.offer(new int[]{i, j});
    50. grid[i][j] = '0';
    51. while(!queue.isEmpty()){
    52. int[] cur = queue.poll();
    53. for(int[] pos : positions){
    54. int newRow = cur[0] + pos[0];
    55. int newColumn = cur[1] + pos[1];
    56. if(newRow < 0 || newRow >= grid.length || newColumn < 0 || newColumn >= grid[0].length || grid[newRow][newColumn] == '0'){
    57. continue;
    58. }
    59. grid[newRow][newColumn] = '0'; // 防止下次for循环将同样的位置(下次计算得到的newRow,newColumn可能会与本次相同)加入queue中,造成死循环
    60. queue.offer(new int[]{newRow, newColumn});
    61. }
    62. }
    63. }
    64. }
    65. class Solution {
    66. int[][] positions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    67. boolean[][] visited; // 通过判断该位置是否被访问过,而不是将1修改为0
    68. public int numIslands(char[][] grid) {
    69. visited = new boolean[grid.length][grid[0].length];
    70. int count = 0;
    71. for(int i = 0; i < grid.length; i++){
    72. for(int j = 0; j < grid[0].length; j++){
    73. if(grid[i][j] == '1' && !visited[i][j]){
    74. count++;
    75. bfs(grid, i, j);
    76. }
    77. }
    78. }
    79. return count;
    80. }
    81. public void bfs(char[][] grid, int i, int j){
    82. Queue<int[]> queue = new LinkedList();
    83. queue.offer(new int[]{i, j});
    84. visited[i][j] = true;
    85. while(!queue.isEmpty()){
    86. int[] cur = queue.poll();
    87. for(int[] pos : positions){
    88. int newRow = cur[0] + pos[0];
    89. int newColumn = cur[1] + pos[1];
    90. if(newRow < 0 || newRow >= grid.length || newColumn < 0 || newColumn >= grid[0].length || grid[newRow][newColumn] == '0' || visited[newRow][newColumn]){
    91. continue;
    92. }
    93. visited[newRow][newColumn] = true;
    94. queue.offer(new int[]{newRow, newColumn});
    95. }
    96. }
    97. }
    98. }

    695. 岛屿的最大面积

    给你一个大小为 m x n 的二进制矩阵 grid 。岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都被 0(代表水)包围着。岛屿的面积是岛上值为 1 的单元格的数目。计算并返回 grid 中最大的岛屿面积。如果没有岛屿,则返回面积为 0 。

    输入:grid = [[0,0,1,0,0,0,0,1,0,0,0,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,1,1,0,1,0,0,0,0,0,0,0,0],[0,1,0,0,1,1,0,0,1,0,1,0,0],[0,1,0,0,1,1,0,0,1,1,1,0,0],[0,0,0,0,0,0,0,0,0,0,1,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,0,0,0,0,0,0,1,1,0,0,0,0]]
    输出:6
    1. // dfs
    2. class Solution {
    3. int area;
    4. public int maxAreaOfIsland(int[][] grid) {
    5. int maxArea = 0;
    6. for(int i = 0; i < grid.length; i++){
    7. for(int j = 0; j < grid[0].length; j++){
    8. if(grid[i][j] == 1){
    9. area = 0;
    10. dfs(grid, i, j);
    11. maxArea = Math.max(maxArea, area);
    12. }
    13. }
    14. }
    15. return maxArea;
    16. }
    17. public void dfs(int[][] grid, int i, int j){
    18. if(i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == 0){
    19. return;
    20. }
    21. area++;
    22. grid[i][j] = 0;
    23. dfs(grid, i - 1, j);
    24. dfs(grid, i + 1, j);
    25. dfs(grid, i, j - 1);
    26. dfs(grid, i, j + 1);
    27. }
    28. }
    1. // bfs
    2. class Solution {
    3. int area;
    4. public int maxAreaOfIsland(int[][] grid) {
    5. int maxArea = 0;
    6. for(int i = 0; i < grid.length; i++){
    7. for(int j = 0; j < grid[0].length; j++){
    8. if(grid[i][j] == 1){
    9. area = 0;
    10. bfs(grid, i, j);
    11. maxArea = Math.max(maxArea, area);
    12. }
    13. }
    14. }
    15. return maxArea;
    16. }
    17. public void bfs(int[][] grid, int i, int j){
    18. Queue<int[]> queue = new LinkedList<>();
    19. queue.offer(new int[]{i, j});
    20. while(!queue.isEmpty()){
    21. int[] cur = queue.poll();
    22. i = cur[0];
    23. j = cur[1];
    24. if(i >= 0 && i < grid.length && j >= 0 && j < grid[0].length && grid[i][j] == 1){
    25. area++;
    26. grid[i][j] = 0;
    27. queue.offer(new int[]{i - 1, j});
    28. queue.offer(new int[]{i + 1, j});
    29. queue.offer(new int[]{i, j - 1});
    30. queue.offer(new int[]{i, j + 1});
    31. }
    32. }
    33. }
    34. }

    463. 岛屿的周长

    给定一个 row x col 的二维网格地图 grid ,其中:grid[i][j] = 1 表示陆地, grid[i][j] = 0 表示水域。网格中的格子 水平和垂直 方向相连(对角线方向不相连)。整个网格被水完全包围,但其中恰好有一个岛屿(或者说,一个或多个表示陆地的格子相连组成的岛屿)。岛屿中没有“湖”(“湖” 指水域在岛屿内部且不和岛屿周围的水相连)。格子是边长为 1 的正方形。网格为长方形,且宽度和高度均不超过 100 。计算这个岛屿的周长。

    示例:输入:grid = [[0,1,0,0],[1,1,1,0],[0,1,0,0],[1,1,0,0]]         输出:16

    1. // dfs
    2. class Solution {
    3. int count = 0;
    4. public int islandPerimeter(int[][] grid) {
    5. for(int i = 0; i < grid.length; i++){
    6. for(int j = 0; j < grid[0].length; j++){
    7. if(grid[i][j] == 1){
    8. dfs(grid, i, j);
    9. }
    10. }
    11. }
    12. return count;
    13. }
    14. public void dfs(int[][] grid, int i, int j){
    15. if(i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == 0){
    16. count++;
    17. return;
    18. }
    19. if(grid[i][j] == 2){
    20. return;
    21. }
    22. grid[i][j] = 2;
    23. dfs(grid, i - 1, j);
    24. dfs(grid, i + 1, j);
    25. dfs(grid, i, j - 1);
    26. dfs(grid, i, j + 1);
    27. }
    28. }
    29. class Solution {
    30. int[][] positions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    31. boolean[][] visited;
    32. int count;
    33. public int islandPerimeter(int[][] grid) {
    34. visited = new boolean[grid.length][grid[0].length];
    35. for(int i = 0; i < grid.length; i++){
    36. for(int j = 0; j < grid[0].length; j++){
    37. if(grid[i][j] == 1 && !visited[i][j]){
    38. dfs(grid, i, j);
    39. }
    40. }
    41. }
    42. return count;
    43. }
    44. public void dfs(int[][] grid, int i, int j){
    45. if(i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == 0){
    46. count++;
    47. return;
    48. }
    49. if(visited[i][j] && grid[i][j] == 1){
    50. return;
    51. }
    52. visited[i][j] = true;
    53. for(int[] pos : positions){
    54. int newRow = i + pos[0];
    55. int newColumn = j + pos[1];
    56. dfs(grid, newRow, newColumn);
    57. }
    58. }
    59. }
    1. // bfs
    2. class Solution {
    3. int count = 0;
    4. public int islandPerimeter(int[][] grid) {
    5. for(int i = 0; i < grid.length; i++){
    6. for(int j = 0; j < grid[0].length; j++){
    7. if(grid[i][j] == 1){
    8. bfs(grid, i, j);
    9. }
    10. }
    11. }
    12. return count;
    13. }
    14. public void bfs(int[][] grid, int i, int j){
    15. Queue<int[]> queue = new LinkedList<>();
    16. queue.offer(new int[]{i, j});
    17. while(!queue.isEmpty()){
    18. int[] cur = queue.poll();
    19. i = cur[0];
    20. j = cur[1];
    21. if(i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == 0){
    22. count++;
    23. continue;
    24. }
    25. if(grid[i][j] == 2){
    26. continue;
    27. }
    28. grid[i][j] = 2;
    29. queue.offer(new int[]{i - 1, j});
    30. queue.offer(new int[]{i + 1, j});
    31. queue.offer(new int[]{i, j - 1});
    32. queue.offer(new int[]{i, j + 1});
    33. }
    34. }
    35. }
    36. class Solution {
    37. int[][] positions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    38. boolean[][] visited;
    39. int count = 0;
    40. public int islandPerimeter(int[][] grid) {
    41. visited = new boolean[grid.length][grid[0].length];
    42. for(int i = 0; i < grid.length; i++){
    43. for(int j = 0; j < grid[0].length; j++){
    44. if(grid[i][j] == 1 && !visited[i][j]){
    45. bfs(grid, i, j);
    46. }
    47. }
    48. }
    49. return count;
    50. }
    51. public void bfs(int[][] grid, int i, int j){
    52. Queue<int[]> queue = new LinkedList<>();
    53. queue.offer(new int[]{i, j});
    54. visited[i][j] = true;
    55. while(!queue.isEmpty()){
    56. int[] cur = queue.poll();
    57. for(int[] pos : positions){
    58. int newRow = cur[0] + pos[0];
    59. int newColumn = cur[1] + pos[1];
    60. if(newRow < 0 || newRow >= grid.length || newColumn < 0 || newColumn >= grid[0].length || grid[newRow][newColumn] == 0){
    61. count++;
    62. continue;
    63. }
    64. if(visited[newRow][newColumn] && grid[newRow][newColumn] == 1){
    65. continue;
    66. }
    67. queue.offer(new int[]{newRow, newColumn});
    68. visited[newRow][newColumn] = true;
    69. }
    70. }
    71. }
    72. }

    827. 最大人工岛屿

    给你一个大小为 n x n 二进制矩阵 grid 。最多 只能将一格 0 变成 1 。返回执行此操作后,grid 中最大的岛屿面积是多少?岛屿 由一组上、下、左、右四个方向相连的 1 形成。

    示例:输入: grid = [[1, 0], [0, 1]]         输出: 3

    1. // dfs
    2. class Solution {
    3. int islandSize; // 每个岛屿的大小
    4. public int largestIsland(int[][] grid) {
    5. int[][] positions = new int[][]{{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
    6. int m = grid.length;
    7. int n = grid[0].length;
    8. Map map = new HashMap<>(); // key为岛屿编号,value为岛屿大小
    9. int islandNumber = 2; // 岛屿编号从2开始,与0和1进行区分
    10. for(int i = 0; i < m; i++){
    11. for(int j = 0; j < n; j++){
    12. if(grid[i][j] == 1){
    13. islandSize = 0;
    14. dfs(grid, i, j, islandNumber);
    15. map.put(islandNumber, islandSize);
    16. islandNumber++;
    17. }
    18. }
    19. }
    20. int result = Integer.MIN_VALUE;
    21. for(int i = 0; i < m; i++){
    22. for(int j = 0; j < n; j++){
    23. if(grid[i][j] != 0){
    24. continue;
    25. }
    26. int curSize = 1;
    27. Set set = new HashSet<>();
    28. for(int[] pos : positions){
    29. int newRow = i + pos[0];
    30. int newColumn = j + pos[1];
    31. if(newRow < 0 || newRow >= m || newColumn < 0 || newColumn >= n || grid[newRow][newColumn] == 0){
    32. continue;
    33. }
    34. islandNumber = grid[newRow][newColumn];
    35. if(set.contains(islandNumber) || !map.containsKey(islandNumber)){
    36. continue;
    37. }
    38. set.add(islandNumber);
    39. curSize += map.get(islandNumber);
    40. }
    41. result = Math.max(result, curSize);
    42. }
    43. }
    44. return result == Integer.MIN_VALUE ? m * n : result;
    45. }
    46. public void dfs(int[][] grid, int i, int j, int islandNumber){
    47. if(i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] != 1){
    48. return;
    49. }
    50. islandSize++;
    51. grid[i][j] = islandNumber;
    52. dfs(grid, i - 1, j, islandNumber);
    53. dfs(grid, i + 1, j, islandNumber);
    54. dfs(grid, i, j - 1, islandNumber);
    55. dfs(grid, i, j + 1, islandNumber);
    56. }
    57. }

    1020. 飞地的数量

    给你一个大小为 m x n 的二进制矩阵 grid ,其中 0 表示一个海洋单元格、1 表示一个陆地单元格。一次 移动 是指从一个陆地单元格走到另一个相邻(上、下、左、右)的陆地单元格或跨过 grid 的边界。返回网格中 无法 在任意次数的移动中离开网格边界的陆地单元格的数量。

    示例:输入:grid = [[0,0,0,0],[1,0,1,0],[0,1,1,0],[0,0,0,0]]         输出:3

    1. // dfs
    2. class Solution {
    3. public int numEnclaves(int[][] grid) {
    4. for(int i = 0; i < grid.length; i++){
    5. if(grid[i][0] == 1){ // 左侧
    6. dfs(grid, i, 0);
    7. }
    8. if(grid[i][grid[0].length - 1] == 1){ // 右侧
    9. dfs(grid, i, grid[0].length - 1);
    10. }
    11. }
    12. for(int j = 1; j < grid[0].length - 1; j++){
    13. if(grid[0][j] == 1){ // 上侧
    14. dfs(grid, 0, j);
    15. }
    16. if(grid[grid.length - 1][j] == 1){ // 下侧
    17. dfs(grid, grid.length - 1, j);
    18. }
    19. }
    20. int count = 0;
    21. for(int i = 0; i < grid.length; i++){
    22. for(int j = 0; j < grid[0].length; j++){
    23. if(grid[i][j] == 1){
    24. count++;
    25. }
    26. }
    27. }
    28. return count;
    29. }
    30. public void dfs(int[][] grid, int i, int j){
    31. if(i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == 0){
    32. return;
    33. }
    34. grid[i][j] = 0;
    35. dfs(grid, i - 1, j);
    36. dfs(grid, i + 1, j);
    37. dfs(grid, i, j - 1);
    38. dfs(grid, i, j + 1);
    39. }
    40. }
    1. // bfs
    2. class Solution {
    3. public int numEnclaves(int[][] grid) {
    4. for(int i = 0; i < grid.length; i++){
    5. if(grid[i][0] == 1){ // 左侧
    6. bfs(grid, i, 0);
    7. }
    8. if(grid[i][grid[0].length - 1] == 1){ // 右侧
    9. bfs(grid, i, grid[0].length - 1);
    10. }
    11. }
    12. for(int j = 1; j < grid[0].length - 1; j++){
    13. if(grid[0][j] == 1){ // 上侧
    14. bfs(grid, 0, j);
    15. }
    16. if(grid[grid.length - 1][j] == 1){ // 下侧
    17. bfs(grid, grid.length - 1, j);
    18. }
    19. }
    20. int count = 0;
    21. for(int i = 0; i < grid.length; i++){
    22. for(int j = 0; j < grid[0].length; j++){
    23. if(grid[i][j] == 1){
    24. count++;
    25. }
    26. }
    27. }
    28. return count;
    29. }
    30. public void bfs(int[][] grid, int i, int j){
    31. Queue<int[]> queue = new LinkedList<>();
    32. queue.offer(new int[]{i, j});
    33. while(!queue.isEmpty()){
    34. int[] cur = queue.poll();
    35. i = cur[0];
    36. j = cur[1];
    37. if(i >= 0 && i < grid.length && j >= 0 && j < grid[0].length && grid[i][j] == 1){
    38. grid[i][j] = 0;
    39. queue.offer(new int[]{i - 1, j});
    40. queue.offer(new int[]{i + 1, j});
    41. queue.offer(new int[]{i, j - 1});
    42. queue.offer(new int[]{i, j + 1});
    43. }
    44. }
    45. }
    46. }

    130. 被围绕的区域

    给你一个 m x n 的矩阵 board ,由若干字符 'X' 和 'O' ,找到所有被 'X' 围绕的区域,并将这些区域里所有的 'O' 用 'X' 填充。

    1. // dfs
    2. class Solution {
    3. public void solve(char[][] board) {
    4. for(int i = 0; i < board.length; i++){
    5. if(board[i][0] == 'O'){
    6. dfs(board, i, 0);
    7. }
    8. if(board[i][board[0].length - 1] == 'O'){
    9. dfs(board, i, board[0].length - 1);
    10. }
    11. }
    12. for(int j = 1; j < board[0].length - 1; j++){
    13. if(board[0][j] == 'O'){
    14. dfs(board, 0, j);
    15. }
    16. if(board[board.length - 1][j] == 'O'){
    17. dfs(board, board.length - 1, j);
    18. }
    19. }
    20. for(int i = 0; i < board.length; i++){
    21. for(int j = 0; j < board[0].length; j++){
    22. if(board[i][j] == 'A'){
    23. board[i][j] = 'O';
    24. }else if(board[i][j] == 'O'){
    25. board[i][j] = 'X';
    26. }
    27. }
    28. }
    29. }
    30. public void dfs(char[][] board, int i, int j){
    31. if(i < 0 || i >= board.length || j < 0 || j >= board[0].length || board[i][j] == 'X'
    32. || board[i][j] == 'A'){
    33. return;
    34. }
    35. board[i][j] = 'A';
    36. dfs(board, i - 1, j);
    37. dfs(board, i + 1, j);
    38. dfs(board, i, j - 1);
    39. dfs(board, i, j + 1);
    40. }
    41. }
    1. // bfs
    2. class Solution {
    3. public void solve(char[][] board) {
    4. for(int i = 0; i < board.length; i++){
    5. if(board[i][0] == 'O'){
    6. bfs(board, i, 0);
    7. }
    8. if(board[i][board[0].length - 1] == 'O'){
    9. bfs(board, i, board[0].length - 1);
    10. }
    11. }
    12. for(int j = 1; j < board[0].length - 1; j++){
    13. if(board[0][j] == 'O'){
    14. bfs(board, 0, j);
    15. }
    16. if(board[board.length - 1][j] == 'O'){
    17. bfs(board, board.length - 1, j);
    18. }
    19. }
    20. for(int i = 0; i < board.length; i++){
    21. for(int j = 0; j < board[0].length; j++){
    22. if(board[i][j] == 'A'){
    23. board[i][j] = 'O';
    24. }else if(board[i][j] == 'O'){
    25. board[i][j] = 'X';
    26. }
    27. }
    28. }
    29. }
    30. public void bfs(char[][] board, int i, int j){
    31. Queue<int[]> queue = new LinkedList<>();
    32. queue.offer(new int[]{i, j});
    33. while(!queue.isEmpty()){
    34. int[] cur = queue.poll();
    35. i = cur[0];
    36. j = cur[1];
    37. if(i >= 0 && i < board.length && j >= 0 && j < board[0].length && board[i][j] == 'O'){
    38. board[i][j] = 'A';
    39. queue.offer(new int[]{i - 1, j});
    40. queue.offer(new int[]{i + 1, j});
    41. queue.offer(new int[]{i, j - 1});
    42. queue.offer(new int[]{i, j + 1});
    43. }
    44. }
    45. }
    46. }

     417. 太平洋大西洋水流问题

    有一个 m × n 的矩形岛屿,与 太平洋 和 大西洋 相邻。 “太平洋” 处于大陆的左边界和上边界,而 “大西洋” 处于大陆的右边界和下边界。这个岛被分割成一个由若干方形单元格组成的网格。给定一个 m x n 的整数矩阵 heights , heights[r][c] 表示坐标 (r, c) 上单元格 高于海平面的高度 。岛上雨水较多,如果相邻单元格的高度 小于或等于 当前单元格的高度,雨水可以直接向北、南、东、西流向相邻单元格。水可以从海洋附近的任何单元格流入海洋。返回网格标 result 的 2D 列表 ,其中 result[i] = [ri, ci] 表示雨水从单元格 (ri, ci) 流动 既可流向太平洋也可流向大西洋 。

    1. // dfs
    2. class Solution {
    3. int[][] positions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    4. public List> pacificAtlantic(int[][] heights) {
    5. int m = heights.length;
    6. int n = heights[0].length;
    7. boolean[][] pacific = new boolean[m][n];
    8. boolean[][] atlantic = new boolean[m][n];
    9. for(int i = 0; i < m; i++){
    10. dfs(heights, pacific, i, 0);
    11. dfs(heights, atlantic, i, n - 1);
    12. }
    13. for(int j = 0; j < n; j++){
    14. dfs(heights, pacific, 0, j);
    15. dfs(heights, atlantic, m - 1, j);
    16. }
    17. List> list = new ArrayList<>();
    18. for(int i = 0; i < m; i++){
    19. for(int j = 0; j < n; j++){
    20. if(pacific[i][j] && atlantic[i][j]){
    21. list.add(new ArrayList<>(Arrays.asList(i, j)));
    22. }
    23. }
    24. }
    25. return list;
    26. }
    27. public void dfs(int[][] heights, boolean[][] ocean, int i, int j){
    28. if(ocean[i][j]){
    29. return;
    30. }
    31. ocean[i][j] = true;
    32. for(int[] pos : positions){
    33. int newRow = i + pos[0];
    34. int newColumn = j + pos[1];
    35. if(newRow < 0 || newRow >= heights.length || newColumn < 0 || newColumn >= heights[0].length || heights[i][j] > heights[newRow][newColumn]){
    36. continue;
    37. }
    38. dfs(heights, ocean, newRow, newColumn);
    39. }
    40. }
    41. }
    1. // bfs
    2. class Solution {
    3. int[][] positions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    4. public List> pacificAtlantic(int[][] heights) {
    5. int m = heights.length;
    6. int n = heights[0].length;
    7. boolean[][] pacific = new boolean[m][n];
    8. boolean[][] atlantic = new boolean[m][n];
    9. for(int i = 0; i < m; i++){
    10. bfs(heights, pacific, i, 0);
    11. bfs(heights, atlantic, i, n - 1);
    12. }
    13. for(int j = 0; j < n; j++){
    14. bfs(heights, pacific, 0, j);
    15. bfs(heights, atlantic, m - 1, j);
    16. }
    17. List> list = new ArrayList<>();
    18. for(int i = 0; i < m; i++){
    19. for(int j = 0; j < n; j++){
    20. if(pacific[i][j] && atlantic[i][j]){
    21. list.add(new ArrayList<>(Arrays.asList(i, j)));
    22. }
    23. }
    24. }
    25. return list;
    26. }
    27. public void bfs(int[][] heights, boolean[][] ocean, int i, int j){
    28. ocean[i][j] = true;
    29. Queue<int[]> queue = new LinkedList<>();
    30. queue.offer(new int[]{i, j});
    31. while(!queue.isEmpty()){
    32. int[] cur = queue.poll();
    33. for(int[] pos : positions){
    34. int newRow = cur[0] + pos[0];
    35. int newColumn = cur[1] + pos[1];
    36. if(newRow < 0 || newRow >= heights.length || newColumn < 0 || newColumn >= heights[0].length || heights[cur[0]][cur[1]] > heights[newRow][newColumn] || ocean[newRow][newColumn]){
    37. continue;
    38. }
    39. ocean[newRow][newColumn] = true;
    40. queue.offer(new int[]{newRow, newColumn});
    41. }
    42. }
    43. }
    44. }

    841. 钥匙和房间

    有 n 个房间,房间按从 0 到 n - 1 编号。最初,除 0 号房间外的其余所有房间都被锁住。你的目标是进入所有的房间。然而,你不能在没有获得钥匙的时候进入锁住的房间。当你进入一个房间,你可能会在里面找到一套不同的钥匙,每把钥匙上都有对应的房间号,即表示钥匙可以打开的房间。你可以拿上所有钥匙去解锁其他房间。给你一个数组 rooms 其中 rooms[i] 是你进入 i 号房间可以获得的钥匙集合。如果能进入 所有 房间返回 true,否则返回 false

    示例1:输入:rooms = [[1],[2],[3],[]]         输出:true

    示例2:输入:rooms = [[1,3],[3,0,1],[2],[0]]         输出:false

    1. // dfs
    2. class Solution {
    3. public boolean canVisitAllRooms(List> rooms) {
    4. boolean[] visited = new boolean[rooms.size()];
    5. dfs(rooms, visited, 0);
    6. for(int i = 0; i < visited.length; i++){
    7. if(!visited[i]){
    8. return false;
    9. }
    10. }
    11. return true;
    12. }
    13. public void dfs(List> rooms, boolean[] visited, int key){
    14. if(visited[key]){
    15. return;
    16. }
    17. visited[key] = true;
    18. List curRoom = rooms.get(key);
    19. for(int i = 0; i < curRoom.size(); i++){
    20. dfs(rooms, visited, curRoom.get(i));
    21. }
    22. }
    23. }
    1. // bfs
    2. class Solution {
    3. public boolean canVisitAllRooms(List> rooms) {
    4. boolean[] visited = new boolean[rooms.size()];
    5. bfs(rooms, visited);
    6. for(int i = 0; i < visited.length; i++){
    7. if(!visited[i]){
    8. return false;
    9. }
    10. }
    11. return true;
    12. }
    13. public void bfs(List> rooms, boolean[] visited){
    14. Queue queue = new LinkedList<>();
    15. queue.offer(0);
    16. while(!queue.isEmpty()){
    17. int curKey = queue.poll();
    18. visited[curKey] = true;
    19. List curRoom = rooms.get(curKey);
    20. for(int i = 0; i < curRoom.size(); i++){
    21. if(visited[curRoom.get(i)]){
    22. continue;
    23. }
    24. queue.offer(curRoom.get(i));
    25. }
    26. }
    27. }
    28. }

    127. 单词接龙

    字典 wordList 中从单词 beginWord 和 endWord 的 转换序列 是一个按下述规格形成的序列 beginWord -> s1 -> s2 -> ... -> sk:①每一对相邻的单词只差一个字母;②对于 1 <= i <= k 时,每个 si 都在 wordList 中。注意, beginWord 不需要在 wordList 中;③sk == endWord。给你两个单词 beginWord 和 endWord 和一个字典 wordList ,返回 从 beginWord 到 endWord 的 最短转换序列 中的 单词数目 。如果不存在这样的转换序列,返回 0 。

    示例:输入:beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]         输出:5;

    解释:一个最短转换序列是 "hit" -> "hot" -> "dot" -> "dog" -> "cog", 返回它的长度 5。

    1. class Solution {
    2. public int ladderLength(String beginWord, String endWord, List wordList) {
    3. Set wordSet = new HashSet<>(wordList); // 转换为HashSet, 加快速度
    4. if(!wordSet.contains(endWord)){
    5. return 0;
    6. }
    7. // bfs 广搜只要搜到了终点,那么一定是最短的路径
    8. Queue queue = new LinkedList<>();
    9. queue.offer(beginWord);
    10. Map map = new HashMap<>(); // 存储单词对应的路径长度
    11. map.put(beginWord, 1);
    12. while(!queue.isEmpty()){
    13. String word = queue.poll();
    14. int pathLen = map.get(word);
    15. for(int i = 0; i < word.length(); i++){
    16. char[] chars = word.toCharArray();
    17. for(char j = 'a'; j <= 'z'; j++){
    18. chars[i] = j;
    19. String newWord = String.valueOf(chars);
    20. if(newWord.equals(endWord)){
    21. return pathLen + 1;
    22. }
    23. if(wordSet.contains(newWord) && !map.containsKey(newWord)){
    24. queue.offer(newWord);
    25. map.put(newWord, pathLen + 1);
    26. }
    27. }
    28. }
    29. }
    30. return 0;
    31. }
    32. }
  • 相关阅读:
    高光谱遥感学习入门丨高光谱数据处理基础、Python和Matlab高光谱遥感数据处理
    aspnetcore6.0源代码编译调试
    EventSystem 事件系统
    spring复习:(60)自定义qualifier
    GoLand 2023:为Go开发者打造的智能IDE mac/win激活版
    IMX6ULL学习笔记(4)——安装并使用交叉编译工具链
    JAVA计算机毕业设计食堂综合评价系统源码+系统+mysql数据库+lw文档
    代码审计之路之白盒挖掘机 | 技术精选01
    MySQL索引
    我的创作纪念日—小梁说代码
  • 原文地址:https://blog.csdn.net/Archer__13/article/details/133933033