代码随想录算法训练营第五十天|卡码网 99 岛屿数量、卡码网 100 最大岛屿的面积

参考文章均来自代码随想录

卡码网 99 岛屿数量

参考文章链接

题目链接

模板题 现在稍微有点熟悉了

还是比较习惯直接终止条件的写法 目前先维持这样 感觉比较好理解

然后定义全局数组那个上下左右方向的 也明白了

深度优先搜索:

cpp 复制代码
#include <iostream>
#include <vector>

using namespace std;

int dir[4][2] = {0, 1, 1, 0, -1, 0, 0, -1}; //四个方向
void dfs(const vector<vector<int>> &grid, vector<vector<bool>> &visited, int x,
         int y) {
  if (grid[x][y] ==0|| visited[x][y])
    return; //终止条件是访问过的节点 或者 遇到海水
  visited[x][y] = true;
  for (int i = 0; i < 4; i++) {
    int nextx = x + dir[i][0];
    int nexty = y + dir[i][1];
    if (nextx < 0 || nextx >= grid.size() || nexty < 0 || nexty >= grid[0].size())
      continue; //越界直接跳过

    dfs(grid, visited, nextx, nexty);
  }
}

int main() {
  int n, m;
  cin >> n >> m;
  vector<vector<int>> grid(n, vector<int>(m, 0));
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> grid[i][j];
    }
  }

  int result = 0;
  vector<vector<bool>> visited(n, vector<bool>(m, false));
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (!visited[i][j] && grid[i][j] == 1) { // 遇到没访问过的陆地,+1
        result++;
        dfs(grid, visited, i, j);
      }
    }
  }
  cout << result << endl;
}

广度优先搜索:要注意标记是否被访问过的时机 否则会造成重复入队而超时

cpp 复制代码
#include <iostream>
#include <vector>
#include <queue>
using namespace std;

int dir[4][2] = {0, 1, 1, 0, -1, 0, 0, -1}; // 四个方向
void bfs(const vector<vector<int>>& grid, vector<vector<bool>>& visited, int x, int y) {
    queue<pair<int, int>> que;
    que.push({x, y});
    visited[x][y] = true; // 只要加入队列,立刻标记
    while(!que.empty()) {
        pair<int ,int> cur = que.front(); que.pop();
        int curx = cur.first;
        int cury = cur.second;
        for (int i = 0; i < 4; i++) {
            int nextx = curx + dir[i][0];
            int nexty = cury + dir[i][1];
            if (nextx < 0 || nextx >= grid.size() || nexty < 0 || nexty >= grid[0].size()) continue;  // 越界了,直接跳过
            if (!visited[nextx][nexty] && grid[nextx][nexty] == 1) {
                que.push({nextx, nexty});
                visited[nextx][nexty] = true; // 只要加入队列立刻标记
            }
        }
    }
}

int main() {
    int n, m;
    cin >> n >> m;
    vector<vector<int>> grid(n, vector<int>(m, 0));
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> grid[i][j];
        }
    }

    vector<vector<bool>> visited(n, vector<bool>(m, false));

    int result = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (!visited[i][j] && grid[i][j] == 1) {
                result++; // 遇到没访问过的陆地,+1
                bfs(grid, visited, i, j); // 将与其链接的陆地都标记上 true
            }
        }
    }


    cout << result << endl;
}

卡码网 100 最大岛屿的面积

参考文章链接

题目链接

和上题差不多 加一个count记录1的个数即可

cpp 复制代码
#include <iostream>
#include <vector>
using namespace std;

int count;
int dir[4][2] = {0, 1, 1, 0, -1, 0, 0, -1}; // 四个方向
void dfs(vector<vector<int>>& grid, vector<vector<bool>>& visited, int x, int y) {
    if (visited[x][y] || grid[x][y] == 0) return; // 终止条件:访问过的节点 或者 遇到海水
    visited[x][y] = true; // 标记访问过
    count++;
    for (int i = 0; i < 4; i++) {
        int nextx = x + dir[i][0];
        int nexty = y + dir[i][1];
        if (nextx < 0 || nextx >= grid.size() || nexty < 0 || nexty >= grid[0].size()) continue;  // 越界了,直接跳过
        dfs(grid, visited, nextx, nexty);
    }
}

int main() {
    int n, m;
    cin >> n >> m;
    vector<vector<int>> grid(n, vector<int>(m, 0));
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> grid[i][j];
        }
    }
    vector<vector<bool>> visited = vector<vector<bool>>(n, vector<bool>(m, false));
    int result = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (!visited[i][j] && grid[i][j] == 1) {
                count = 0; // 因为dfs处理当前节点,所以遇到陆地计数为0,进dfs之后在开始从1计数
                dfs(grid, visited, i, j); // 将与其链接的陆地都标记上 true
                result = max(result, count);
            }
        }
    }
    cout << result << endl;
}
相关推荐
青山木13 小时前
Hot 100 --- 划分字母区间
java·数据结构·算法·leetcode·贪心算法
Sunsets_Red13 小时前
浅谈扫描线
c++·算法·编程·题解·洛谷·扫描线·信息学竞赛
a1879272183113 小时前
【算法】双指针与滑动窗口(一):框架总纲——三类问题、一个原理与判决书
算法·leetcode·区间·双指针·滑动窗口·原理·算法讲解
shehuiyuelaiyuehao13 小时前
算法42,模拟算法,模拟z字形变换
算法
朝朝辞暮i14 小时前
C++第一课
开发语言·c++·算法
橘子汽水16814 小时前
Leetcode 208,207实现Trie前缀树,课程表
java·数据结构·算法·leetcode
hanlin0314 小时前
刷题笔记:力扣第169题-多数元素
笔记·算法·leetcode
hfywmsj14 小时前
广州餐饮铺位招租数据建模:基于多维评估体系的选址算法设计与实现
人工智能·算法·广州餐饮铺位招租
wabs66614 小时前
关于二叉树【力扣116.填充每个节点的下一个右侧节点指针的思考】
数据结构·c++·算法·leetcode·二叉树·层序遍历
Nil20814 小时前
leetcode 74搜索二维矩阵
算法·leetcode·矩阵