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偏移使地址越界。