首页 > 编程语言 >「代码随想录算法训练营」第四十四天 | 图论 part2

「代码随想录算法训练营」第四十四天 | 图论 part2

时间:2024-08-22 19:39:09浏览次数:15  
标签:cur int 第四十四 随想录 part2 grid size col row

200. 岛屿数量

题目链接:https://leetcode.cn/problems/number-of-islands/description/
文章讲解:https://programmercarl.com/kamacoder/0099.岛屿的数量深搜.html
题目难度:中等
题目状态:看题解

思路一:深搜版

方法 dfs

  • 参数: 接受一个字符网格 grid 和当前坐标 (r, c)
  • 功能: 将当前岛屿的所有相连部分标记为已访问。
  • 实现:
    • 改变当前坐标的值为 '0',表示已访问。
    • 检查上下左右四个方向,如果相邻位置是 '1',递归调用 dfs

方法 numIslands

  • 参数: 接受一个字符网格 grid
  • 功能: 计算网格中岛屿的数量。
  • 实现:
    • 获取网格的行数 nr 和列数 nc
    • 初始化岛屿计数器 num_islands 为 0。
    • 遍历网格中的每个元素,如果遇到 '1'
      • 增加岛屿计数器。
      • 调用 dfs 方法,从该位置开始将整个岛屿标记为已访问。
    • 返回岛屿的总数。

代码一:

class Solution {
public:
    void dfs(vector<vector<char>> &grid, int r, int c) {
        int nr = grid.size();
        int nc = grid[0].size();
        grid[r][c] = '0';
        if(r - 1 >= 0 && grid[r - 1][c] == '1') dfs(grid, r - 1, c);
        if(r + 1 < nr && grid[r + 1][c] == '1') dfs(grid, r + 1, c);
        if(c - 1 >= 0 && grid[r][c - 1] == '1') dfs(grid, r, c - 1);
        if(c + 1 < nc && grid[r][c + 1] == '1') dfs(grid, r, c + 1);
    }

    int numIslands(vector<vector<char>>& grid) {
        int nr = grid.size();
        if(!nr) return 0;
        int nc = grid[0].size();
        
        int num_islands = 0;
        for(int r = 0; r < nr; ++r) {
            for(int c = 0; c < nc; ++c) {
                if(grid[r][c] == '1') {
                    ++num_islands;
                    dfs(grid, r, c);
                }
            }
        }
        return num_islands;
    }
};

消耗一:

image

思路二:广搜版

思路在代码中。

代码二:

class Solution {
public:
    int numIslands(vector<vector<char>>& grid) {
        int rowCount = grid.size();
        int colCount = grid[0].size();
        // 用来记录岛屿数量
        int num_islands = 0;
        for (int row = 0; row < rowCount; row++) {
            for (int col = 0; col < colCount; col++) {
                // 如果当前点是岛屿的一部分
                if (grid[row][col] == '1') {
                    // 岛屿数量增加
                    num_islands++;
                    // 将当前位置标记为'0', 表示已访问
                    grid[row][col] = '0';
                    // 创建一个队列, 用于存储岛屿的所有相邻点
                    queue<pair<int, int>> neighbors; 
                    // 将当前位置加入队列
                    neighbors.emplace(row, col);
                    // 当队列不为空时,继续搜索
                    while (!neighbors.empty()) {
                        auto [row, col] = neighbors.front();
                        neighbors.pop();
                        // 检查并将当前点的上下左右四个相邻点加入队列(如果它们是未访问的岛屿部分)
                        if (row - 1 >= 0 && grid[row - 1][col] == '1') {
                            neighbors.emplace(row - 1, col);
                            grid[row - 1][col] = '0'; // 标记为已访问
                        }
                        if (row + 1 < rowCount && grid[row + 1][col] == '1') {
                            neighbors.emplace(row + 1, col);
                            grid[row + 1][col] = '0'; // 标记为已访问
                        }
                        if (col - 1 >= 0 && grid[row][col - 1] == '1') {
                            neighbors.emplace(row, col - 1);
                            grid[row][col - 1] = '0'; // 标记为已访问
                        }
                        if (col + 1 < colCount && grid[row][col + 1] == '1') {
                            neighbors.emplace(row, col + 1);
                            grid[row][col + 1] = '0'; // 标记为已访问
                        }
                    }
                }
            }
        }
        return num_islands;
    }
};

消耗二:

image

695. 岛屿的最大面积

题目链接:https://leetcode.cn/problems/max-area-of-island/description/
文章讲解:https://programmercarl.com/kamacoder/0100.岛屿的最大面积.html
题目难度:中等
题目状态:看题解

DFS解法

思路:

  • 方法 IslandDFS:这是一个递归方法,用于计算单个岛屿的面积。

    • 参数
      • grid:二维网格,表示地图。
      • ij:当前格子的行和列索引。
    • 逻辑
      • 检查当前索引是否在网格范围内。
      • 如果当前格子是水(值为0),返回0。
      • 如果是陆地(值为1),将其标记为0(已访问),然后递归地检查四个方向(上、下、左、右)的相邻格子。
      • 返回值为1(当前格子)加上所有相邻陆地格子的面积。
  • 方法 maxAreaOfIsland:计算网格中所有岛屿的最大面积。

    • 逻辑
      • 初始化最大面积 ans 为0。
      • 遍历网格的每个格子。
      • 对于每个陆地格子,调用 IslandDFS 计算该岛屿的面积,并更新最大面积。
      • 返回最大面积。

代码:

class Solution {
public:
    int IslandDFS(vector<vector<int>> &grid, int i, int j) {
        if((i < grid.size()) && (i >= 0) && (j < grid[0].size()) && (j >= 0)) {
            if(grid[i][j] == 0) return 0;
            else {
                grid[i][j] = 0;
                return 1 + IslandDFS(grid, i - 1, j) + IslandDFS(grid, i + 1, j) + IslandDFS(grid, i, j - 1) + IslandDFS(grid, i, j + 1);
            }
        } else 
            return 0;
    }

    int maxAreaOfIsland(vector<vector<int>>& grid) {
        int ans = 0;
        for(int i = 0; i < grid.size(); ++i) {
            for(int j = 0; j < grid[0].size(); ++j) {
                ans = max({ans, IslandDFS(grid, i, j)});
            }
        }
        return ans;
    }
};

消耗:

image

BFS解法

看不懂。。。

代码:

class Solution {
public:
    int maxAreaOfIsland(vector<vector<int>>& grid) {
        int ans = 0;
        for (int i = 0; i != grid.size(); ++i) {
            for (int j = 0; j != grid[0].size(); ++j) {
                int cur = 0;
                queue<int> queuei;
                queue<int> queuej;
                queuei.push(i);
                queuej.push(j);
                while (!queuei.empty()) {
                    int cur_i = queuei.front(), cur_j = queuej.front();
                    queuei.pop();
                    queuej.pop();
                    if (cur_i < 0 || cur_j < 0 || cur_i == grid.size() || cur_j == grid[0].size() || grid[cur_i][cur_j] != 1) {
                        continue;
                    }
                    ++cur;
                    grid[cur_i][cur_j] = 0;
                    int di[4] = {0, 0, 1, -1};
                    int dj[4] = {1, -1, 0, 0};
                    for (int index = 0; index != 4; ++index) {
                        int next_i = cur_i + di[index], next_j = cur_j + dj[index];
                        queuei.push(next_i);
                        queuej.push(next_j);
                    }
                }
                ans = max(ans, cur);
            }
        }
        return ans;
    }
};

标签:cur,int,第四十四,随想录,part2,grid,size,col,row
From: https://www.cnblogs.com/frontpen/p/18371217

相关文章

  • 给自己复盘的随想录笔记-移除元素
    双指针法双指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。定义快慢指针快指针:寻找新数组的元素,新数组就是不含有目标元素的数组慢指针:指向更新新数组下标的位置相关题目删除有序数组中的重复项解题思路:解法:双指针首先注意数组......
  • 给自己复盘用的随想录笔记day1-二分查找
    二分法使用情景数组为有序数组,同时题目还强调数组中无重复元素,因为一旦有重复元素,使用二分查找法返回的元素下标可能不是唯一的,这些都是使用二分法的前提条件,当大家看到题目描述满足如上条件的时候,可要想一想是不是可以用二分法了。求某一个整数的平方根边界条件写二分法......
  • 代码随想录 -- 数组 -- 螺旋矩阵II
    59.螺旋矩阵II-力扣(LeetCode)每画一条边都要坚持一致的左闭右开注意处理n为奇数时的矩阵中心点classSolution(object):defgenerateMatrix(self,n):res=[[0]*nforainrange(n)]startX=0startY=0loop=mid=n/2c......
  • 代码随想录 -- 数组 -- 区间和
    58.区间和(第九期模拟笔试)(kamacoder.com)暴力解法大概率超时,应采用前缀和解法p[i] 表示vec[0]到vec[i]的累加和求vec[m] 到vec[n] 的和只需要 p[n]-p[m] 即可知识点input函数Python3 中raw_input()和input()进行了整合,去除了raw_input(),仅保留了i......
  • 代码随想录day37 || 518 零钱兑换,377 组合总和iv,70 爬楼梯
    0-1背包问题在0-1背包问题中,每种物品只能选择一次,因此一旦选择某个物品后,剩余的容量只能放入前面的物品。这就是为什么状态转移方程是:dp[i][j]=max(dp[i-1][j],dp[i-1][j-w(i)]+v(i))这里的dp[i-1][j-w(i)]+v(i)表示选择第(i)个物品后,剩余的容量只能放入前(......
  • 代码随想录Day22
    77.组合给定两个整数n和k,返回范围[1,n]中所有可能的k个数的组合。你可以按任何顺序返回答案。示例1:输入:n=4,k=2输出:[[2,4],[3,4],[2,3],[1,2],[1,3],[1,4],]示例2:输入:n=1,k=1输出:[[1]]提示:1<=n<=201<=k<=n正解......
  • 代码随想录day36 || 1049 最后一筐石头重量||, 494 目标和,474 一和零
    1049最后一块石头重量||funclastStoneWeightII(stones[]int)int{ //本题思路在于要想得到最小差,就要尽可能将石头分割为两堆相近的重量,然后转换为背包问题 //dp[i]表示容量i背包能装的石头总价值,其中重量和价值相等 //递推公式dp[j]=max(dp[j],dp[j-w(i)]+v[i]......
  • 「代码随想录算法训练营」第四十三天 | 图论 part1
    797.所有可能的路径题目链接:https://leetcode.cn/problems/all-paths-from-source-to-target/description/文章讲解:https://programmercarl.com/kamacoder/0098.所有可达路径.html题目难度:中等题目状态:看题解思路一:DFSvoiddfs(vector<vector<int>>&graph,intx,intn......
  • 代码随想录Day21
    669.修剪二叉搜索树给你二叉搜索树的根节点root,同时给定最小边界low和最大边界high。通过修剪二叉搜索树,使得所有节点的值在[low,high]中。修剪树不应该改变保留在树中的元素的相对结构(即,如果没有被移除,原有的父代子代关系都应当保留)。可以证明,存在唯一的答案。所......
  • 「代码随想录算法训练营」第四十二天 | 单调栈 part2
    42.接雨水题目链接:https://leetcode.cn/problems/trapping-rain-water/文章讲解:https://programmercarl.com/0042.接雨水.html题目难度:困难视频讲解:https://www.bilibili.com/video/BV1uD4y1u75P/题目状态:这道题目在LeetCodeTop100中做过,使用两种方法,再回顾一下思路一:单......