200. Number of Islands

本文深入解析了求解二维网格中岛屿数量的两种经典算法:深度优先搜索(DFS)与广度优先搜索(BFS),并提供了详细的代码实现。通过对比不同算法的优缺点,帮助读者理解如何高效地解决岛屿数量问题。

200. Number of Islands


Given a 2d grid map of '1’s (land) and '0’s (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.

Example 1:

Input:
11110
11010
11000
00000

Output: 1

Example 2:

Input:
11000
11000
00100
00011

Output: 3

方法1: DFS

花花酱: https://www.youtube.com/watch?v=XSmgFKe-XYU

思路:这里在循环里按扫描顺序发起dfs,结束后所有与发起点相连的陆地均被沉没。扫描一个起点沉没一片大陆,当下一次扫描时便不会重复计数小岛数量。

这道题和286. Walls and Gates, 130. surrounded region一起看。
286题的dfs条件是:如果不超边界,且当前解比之前解更好,则推进dfs,否则终止
130题的dfs条件是:如果不超边界,且当前格点为’O’,则推进dfs,否则终止
200题的dfs条件是:如果不超边界,且当前格点是小岛‘1’, 则推进dfs,否则终止

易错点:

  1. 要先判断边界再判断rooms[i][j]当前值,否则会heap-overflow
  2. 注意边界值
    条件举例:(200题)
    if (i < 0 || i >= rooms.size() || j < 0 || j >= rooms[i].size() || rooms[i][j] < val) return;
class Solution {
public:
    int numIslands(vector<vector<char>>& grid) {
        if (grid.size() == 0 || grid[0].size() == 0) return 0;
        int result;
        
        for (int i = 0; i < grid.size(); i ++){
            for (int j = 0; j < grid[0].size(); j++){
                if (grid[i][j] == '1'){
                    result ++;
                    dfs(grid, i, j);
                }
                 
            }
        }
        return result;
    }
    
    void dfs(vector<vector<char>> & grid, int i, int j){
        if (i < 0 || i >= grid.size() || j < 0 || j >= grid[0].size()|| grid[i][j] == '0'){
            return;
        }
        grid[i][j] = '0';
        dfs(grid, i - 1, j);
        dfs(grid, i + 1, j);
        dfs(grid, i, j - 1);
        dfs(grid, i, j + 1);
        
        return;
    }
};

方法2: BFS

class Solution
{
public:
int numIslands(vector<vector> &grid)
{
if(grid.size() == 0 || grid[0].size() == 0)
return 0;

     int res = 0;
     for(int i = 0; i < grid.size(); ++ i)
         for(int j = 0; j < grid[0].size(); ++ j)
             if(grid[i][j] == '1')
             {
                 ++ res;
                 BFS(grid, i, j);
             }
     return res;
 }
private:
void BFS(vector<vector> &grid, int x, int y)
{
	queue<vector> q;
	q.push({x, y});
	grid[x][y] = '0';

     while(!q.empty())
     {
         x = q.front()[0], y = q.front()[1];
         q.pop();
         
         if(x > 0 && grid[x - 1][y] == '1')
         {
             q.push({x - 1, y});
             grid[x - 1][y] = '0';
         }
         if(x < grid.size() - 1 && grid[x + 1][y] == '1')
         {
             q.push({x + 1, y});
             grid[x + 1][y] = '0';
         }
         if(y > 0 && grid[x][y - 1] == '1')
         {
             q.push({x, y - 1});
             grid[x][y - 1] = '0';
         }
         if(y < grid[0].size() - 1 && grid[x][y + 1] == '1')
         {
             q.push({x, y + 1});
             grid[x][y + 1] = '0';
         }
     }
 }
};
class Solution {
public:
    int numIslands(vector<vector<char>>& grid) {
        if (grid.size() == 0 || grid[0].size() == 0) return 0;
        int result = 0;
        vector<vector<bool>> visited(grid.size(), vector<bool>(grid[0].size(), false));
        
        for (int i = 0; i < grid.size(); i++) {
            for (int j = 0; j < grid[0].size(); j++) {
                if (!visited[i][j] && grid[i][j] == '1') {
                    bfs(grid, visited, i, j);
                    result++;
                }
            }
        }
        return result;
    }
    
    void bfs(vector<vector<char>> & grid, vector<vector<bool>> & visited, int i, int j) {
        queue<pair<int, int>> q;
        q.push({i, j});
        
        while(!q.empty()) {
            auto top = q.front();
            q.pop();
            
            int x = top.first;
            int y = top.second;
            
            grid[x][y] = '0';
            
            if (x > 0 && !visited[x - 1][y]) {
                visited[x - 1][y] = true;
                if (grid[x - 1][y] == '1') q.push({x - 1, y});
            }
            
            if (x < grid.size() - 1 && !visited[x + 1][y]) {
                visited[x + 1][y] = true;
                if (grid[x + 1][y] == '1') q.push({x + 1, y});
            }
            
            if (y > 0 && !visited[x][y - 1]) {
                visited[x][y - 1] = true;
                if (grid[x][y - 1] == '1') q.push({x, y - 1});
            }
            
            if (y < grid[0].size() - 1 && !visited[x][y + 1]) {
                visited[x][y + 1] = true;
                if (grid[x][y + 1] == '1') q.push({x, y + 1});
            }
            
        }
        return;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值