LeetCode200岛屿数量

200. 岛屿数量

给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。

示例 1:

输入:
11110
11010
11000
00000
输出: 1

示例 2:

输入:
11000
11000
00100
00011
输出: 3
通过次数 70,766
提交次数 148,095
class Solution:
    def numIslands(self, grid: List[List[str]]) -> int:
        num_isl = 0
        gsize = (len(grid), len(grid[0]))


        visited = [[False for _ in range(gsize[1])] for _ in range(gsize[0])]
        for i in range(gsize[0]):
            for j in range(gsize[1]):
                if grid[i][j] == '1' and visited[i][j] == False:
                    visited[i][j] = True
                    self.DFS((i, j), visited, grid)
                    num_isl += 1
        return num_isl

    def BFS(self, xy, visited, grid):
        gsize = (len(grid), len(grid[0]))
        q = []
        q.append(xy)
        while len(q):
            cur_x, cur_y = q.pop(0)
            directions = [(0, 1), (0, -1), (-1, 0), (1, 0)]
            for delta_x, delta_y in directions:
                next_x = cur_x + delta_x
                next_y = cur_y + delta_y
                
                if (0 <= next_x < gsize[0]) and (0 <= next_y < gsize[1]) and grid[next_x][next_y] == "1" and visited[next_x][next_y] == False:
                    q.append((next_x, next_y))
                    visited[next_x][next_y] = True

    def DFS(self, xy, visited, grid):
        gsize = (len(grid), len(grid[0]))
        cur_x, cur_y = xy
        directions = [(0, 1), (0, -1), (-1, 0), (1, 0)]
        for delta_x, delta_y in directions:
            next_x = cur_x + delta_x
            next_y = cur_y + delta_y
            
            if (0 <= next_x < gsize[0]) and (0 <= next_y < gsize[1]) and grid[next_x][next_y] == "1" and visited[next_x][next_y] == False:
                visited[next_x][next_y] = True
                self.DFS((next_x, next_y), visited, grid)


法一:算法笔记上的模板(使用inq,引入inq的思路不能称之为好)

struct node{
    int x, y;
    node(int _x, int _y):x(_x),y(_y){}
    node(){}
};
class Solution {
private: //使得成员函数共用数据成员,避免了复杂的传参
    int n;
    int m;
    vector<vector<char>>gridTmp;  
    vector<vector<bool> >inq;
    int deltaX[4] = {-1, 1, 0, 0};
    int deltaY[4] = {0, 0, -1, 1};
public:
    int numIslands(vector<vector<char>>& grid) {
        gridTmp = grid;
        n = grid.size();
        if(0==n)
            return 0;
        m = grid[0].size();
        vector<bool> tmp(m, false);
        inq.resize(n, tmp);

        int cnt = 0;
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++){
                if('1'==gridTmp[i][j] && false==inq[i][j]){
                    cnt++;
                    BFS(node(i,j));
                }
            }
        return cnt;
    }
    void BFS(node Node){
        queue<node> Q;
        Q.push(Node);
        inq[Node.x][Node.y] = true;
        while(!Q.empty()){
            node top = Q.front();
            Q.pop();
            int x = top.x;
            int y = top.y;
            for(int i=0; i<4; i++){
                int newX = x+deltaX[i];
                int newY = y+deltaY[i];
                if(judge(newX, newY)){
                    Q.push(node(newX, newY));
                    inq[newX][newY] = true;
                }
            }
        }
    }
    bool judge(int x, int y){ 
        //顺序不对导致越界问题
        if(x>=0 && x<n && y>=0 && y<m && false==inq[x][y] && '1'==gridTmp[x][y])
            return true;
        else
            return false;
    }
};

在这里插入图片描述
法二:不使用inq,直接修改图g(相对简易易理解),若不想修改g,可设一个私有成员gTmp

struct node{
    int x, y;
    node(int _x, int _y):x(_x),y(_y){}
    node(){}
};
class Solution {  
public:
    int numIslands(vector<vector<char>>& grid) {
        int n = grid.size();
        if(0==n)
        	return 0;
        int m = grid[0].size();
        
        int deltaX[4] = {0, 0, -1, 1};
	    int deltaY[4] = {-1, 1, 0, 0}; 

        int cnt = 0;
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++){
                if('1'==grid[i][j]){
                    cnt++;
                    //BFS
                    queue<node> Q;
			        Q.push(node(i,j));
			        grid[i][j] = '0';
			        while(!Q.empty()){
			            node top = Q.front();
			            Q.pop();
			            int x = top.x;
			            int y = top.y;
			            for(int k=0; k<4; k++){
			                int newX = x+deltaX[k];
			                int newY = y+deltaY[k];
			                //顺序不对导致越界
			                if(newX>=0 && newX<n && newY>=0 && newY<m && '1'==grid[newX][newY]){
			                    Q.push(node(newX, newY));
			                    grid[newX][newY] = '0';
			                } 
			            }
			        }
    			}
    		}
        return cnt;
    }
};

在这里插入图片描述
法三DFS

struct node{
    int x, y;
    node(int _x, int _y):x(_x),y(_y){}
    node(){}
};
class Solution {  
private: //私有数据所有成员函数共用,相当于C中的全局变量
    int n, m;
    vector<vector<char>> gridTmp;
    int deltaX[4] = {0, 0, -1, 1};
	int deltaY[4] = {-1, 1, 0, 0};
public:
    void dfs(node Node){
        for(int i=0; i<4; i++){
            int newX = Node.x+deltaX[i];
            int newY = Node.y+deltaY[i];
            //顺序,短路的先后
            if(newX>=0 && newX<n && newY>=0 && newY<m && '1'==gridTmp[newX][newY]){
                gridTmp[newX][newY] = '0';
                dfs(node(newX, newY));
            }
        }
    }
    int numIslands(vector<vector<char>>& grid) {
        n = grid.size();
        if(0==n)
        	return 0;
        m = grid[0].size();
        gridTmp = grid;
        
        int cnt = 0;
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++){
                if('1'==gridTmp[i][j]){
                    cnt++;
                    //DFS
                    gridTmp[i][j] = '0';
                    dfs(node(i,j));
                }
            }
                 
        return cnt;
    }
};

在这里插入图片描述

所得:
1.vector<vector<int> >vc的初始化问题,resize方法。
2.delta偏移使地址越界。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值