• 算法|图论 2


    LeetCode 695- 岛屿的最大面积

    题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

    题目描述:给你一个大小为 m x n 的二进制矩阵 grid 。

    岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都被 0(代表水)包围着。

    岛屿的面积是岛上值为 1 的单元格的数目。

    计算并返回 grid 中最大的岛屿面积。如果没有岛屿,则返回面积为 0 。

    解题思路

    思路一(深度优先遍历):

    1. 首先确定递归函数的参数,返回值。本题要路径,我们直接设置两个全局变量res和tmp,这样可以不用写太多参数传递。返回值就是void,参数需要图和一个x和y来记录当前在哪个岛屿。下次从这个岛屿开始走的。
    2. 确定终止条件,本题按我们的逻辑,先进入循环再判断是否应该终止,那么终止条件就是:当超出网格范围 或 该岛屿已经是海洋 就终止。
    3. 单层处理逻辑,每次将当前岛屿淹没,并且让这片岛屿的面积++(因为我们是确定了当前是陆地才会进入下层递归)。
    1. class Solution {
    2. public:
    3. int res = 0;//记录最大面积
    4. int tmp = 0;//当前这片岛屿的面积
    5. int maxAreaOfIsland(vector<vector<int>>& grid) {
    6. for (int i = 0; i < grid.size(); i++) {
    7. for (int j = 0; j < grid[0].size(); j++) {
    8. if (grid[i][j] == 1) {
    9. dfs(grid, i, j);
    10. //当这次递归结束的时候,说明这片岛屿已经全部被淹没了,此时我们可以记录一下
    11. //这片岛屿的面积,并将tmp置为0,也就是下一片岛屿从新计算大小
    12. res = max(res,tmp);
    13. tmp = 0;
    14. }
    15. }
    16. }
    17. return res;
    18. }
    19. public:
    20. void dfs(vector<vector<int>>& grid, int i, int j) {
    21. if (i < 0 || j < 0 || i >= grid.size() || j >= grid[0].size() || grid[i][j] != 1){
    22. return;
    23. }
    24. grid[i][j] = 0;
    25. //当前如果是陆地那么就让岛屿大小++
    26. tmp++;
    27. dfs(grid, i + 1, j);
    28. dfs(grid, i - 1, j);
    29. dfs(grid, i, j + 1);
    30. dfs(grid, i, j - 1);
    31. }
    32. };

    思路二(广度优先遍历):

    与之前一题一样,就是多一个计算每片岛屿面积的tmp

    1. class Solution {
    2. public:
    3. int res = 0;
    4. int tmp = 0;
    5. int dir[4][2] = {0,1,1,0,-1,0,0,-1};
    6. int maxAreaOfIsland(vector<vector<int>>& grid) {
    7. for(int i=0;i<grid.size();i++){
    8. for(int j=0;j<grid[0].size();j++){
    9. if(grid[i][j] == 1){
    10. bfs(grid,i,j);
    11. res = max(res,tmp);
    12. tmp = 0;
    13. }
    14. }
    15. }
    16. return res;
    17. }
    18. void bfs(vector<vector<int>> &grid,int x,int y){
    19. queue<pair<int,int>> que;
    20. que.push({x,y});
    21. grid[x][y] = 0;
    22. tmp++;//这里也要面积++,因为第一次进入也淹没了一个小岛屿。
    23. while(!que.empty()){
    24. pair<int,int> cur = que.front();
    25. que.pop();
    26. int curx = cur.first;
    27. int cury = cur.second;
    28. for(int i=0;i<4;i++){
    29. int nextx = curx + dir[i][0];
    30. int nexty = cury + dir[i][1];
    31. if(nextx < 0 || nexty < 0 || nextx >= grid.size() || nexty >= grid[0].size() ||grid[nextx][nexty] != 1) continue;
    32. que.push({nextx,nexty});
    33. grid[nextx][nexty] = 0;
    34. tmp++;
    35. }
    36. }
    37. }
    38. };

    总结:

    • 深搜和广搜的问题,这题的广搜需要注意,只要淹没就得加面积的。

    LeetCode 1020- 飞地的数量

    题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

    题目描述:给你一个大小为 m x n 的二进制矩阵 grid ,其中 0 表示一个海洋单元格、1 表示一个陆地单元格。一次 移动 是指从一个陆地单元格走到另一个相邻(上、下、左、右)的陆地单元格或跨过 grid 的边界。

    返回网格中 无法 在任意次数的移动中离开网格边界的陆地单元格的数量。

    解题思路

    思路一(深度优先遍历):

    1. 首先确定递归函数的参数,返回值。本题不需要这些。不过这题我们要设置一个全局变量cango表示是否能走到界外。为false不能走到界外,为true则可以走到界外。
    2. 确定终止条件,本题按我们的逻辑,先进入循环再判断是否应该终止,那么终止条件就是:当超出网格范围 当前遍历的是海洋 就终止。不过这里需要注意,这道题目需要求的是不能走到界外的岛屿的数量。所以终止条件处理的时候有些区别。当出界的时候就将cango设置为true表示可以走出界并返回。当遇到的是海洋,就直接返回。
    1. 单层处理逻辑,每次我们将当前岛屿的值设置为0,模拟为被淹没,并且去淹没当前节点的上下左右相邻的节点。为1的节点为陆地状态,并且将tmp++,表示相连的岛屿数量加一。在每次递归完出来的时候,说明走完了这一片岛屿,我们可以看看是否能走出界,不能则将tmp 加到res中,并且将tmp置为0(cango不做操作,因为默认不能走出去)。可以则将cango置为false,并且将tmp置为0。直到这片海域没有岛屿为止。
    1. class Solution {
    2. public:
    3. int res = 0;
    4. int tmp = 0;
    5. bool cango = false;//标记当前这片岛屿能否走到界外
    6. void dfs(vector<vector<int>> &grid,int x,int y){
    7. //若到达界外,则标记为true,返回
    8. if(x < 0 || y < 0 || x >= grid.size() || y >= grid[0].size()){
    9. cango = true;
    10. return ;
    11. }
    12. //若是海洋,也返回
    13. if(grid[x][y] == 0) return;
    14. //将岛屿淹没
    15. grid[x][y] = 0;
    16. //这片岛屿数量加一
    17. tmp ++;
    18. dfs(grid,x+1,y);
    19. dfs(grid,x-1,y);
    20. dfs(grid,x,y+1);
    21. dfs(grid,x,y-1);
    22. }
    23. int numEnclaves(vector<vector<int>>& grid) {
    24. int m = grid.size(),n = grid[0].size();
    25. for(int i=0;i<m;i++){
    26. for(int j=0;j<n;j++){
    27. //若遇到岛屿,则进行深度优先遍历
    28. if(grid[i][j] == 1){
    29. dfs(grid,i,j);
    30. //若标记为不能走到边界,则将tmp加到结果中
    31. if(cango == false){
    32. res += tmp;
    33. //将tmp清零
    34. tmp = 0;
    35. }else{
    36. //若无法走到边界,则将cango改为默认值false
    37. tmp = 0;
    38. cango = false;
    39. }
    40. }
    41. }
    42. }
    43. return res;
    44. }
    45. };

    思路二(广度优先遍历):

    就是多了一个不能走出界则将岛屿数加到结果中的操作。

    1. class Solution {
    2. public:
    3. int tmp = 0;
    4. int res = 0;
    5. bool cango = false;//标记是否能走到界外
    6. int dir[4][2] = {0,1,1,0,-1,0,0,-1};
    7. void bfs(vector<vector<int>> &grid,int x,int y){
    8. queue<pair<int,int>> que;//存储对组的队列,存坐标用的
    9. que.push({x,y});//压入当前的坐标
    10. grid[x][y] = 0;//淹没当前岛屿
    11. tmp ++;//只要有淹没,就tmp++
    12. while(!que.empty()){
    13. pair<int,int> cur = que.front();//取出队头元素
    14. que.pop();//弹出队头
    15. for(int i=0;i<4;i++){
    16. //遍历四个方向,看是否有岛屿
    17. int nextx = cur.first + dir[i][0];
    18. int nexty = cur.second + dir[i][1];
    19. if(nextx < 0 || nexty < 0 || nextx >= grid.size() || nexty >= grid[0].size()){
    20. cango = true;
    21. continue;
    22. }
    23. if(0 == grid[nextx][nexty]) continue;
    24. tmp++;
    25. que.push({nextx,nexty});
    26. grid[nextx][nexty] = 0;
    27. }
    28. }
    29. }
    30. int numEnclaves(vector<vector<int>>& grid) {
    31. int m = grid.size(),n = grid[0].size();
    32. for(int i=0;i<m;i++){
    33. for(int j=0;j<n;j++){
    34. if(grid[i][j] == 1){
    35. bfs(grid,i,j);
    36. if(false == cango){
    37. res += tmp;
    38. }else{
    39. cango = false;
    40. }
    41. tmp = 0;
    42. }
    43. }
    44. }
    45. return res;
    46. }
    47. };

    总结:

    • 多了一个加岛屿的操作。
  • 相关阅读:
    问题处理: Keil5没有AT89C51芯片
    低代码与数据分析:重塑软件开发与数据分析的未来
    《优化接口设计的思路》系列:第七篇—接口限流策略
    【AGC】如何在iOS上集成华为AGC应用内消息
    圆环进度条 两种实现方式
    6 HTTP&Tomcat&Servlet详解
    图解Dijkstra算法+代码实现
    vue v-for 渲染大量数据卡顿的优化方案
    MySQL如何导入大量数据?
    AI:人工智能领域有影响力的开源社区/科技巨头研究机构/全球顶尖学府实验室的简介、课程学习(正确姿势薅羊毛)之详细攻略
  • 原文地址:https://blog.csdn.net/m0_47893709/article/details/132895839