更加丰富内容可查看我的个人博客:xukang’s blog
这道题其实就是图的遍历,将值为“1”
的元素组成一个无向图,遍历这个无向图
方法1、DFS
设目前指针指向一个岛屿中的某一点
(i, j)
,寻找包括此点的岛屿边界。从
(i, j)
向此点的上下左右(i+1,j),(i-1,j),(i,j+1),(i,j-1)
做深度搜索。终止条件:
(i, j)
越过矩阵边界;
grid[i][j] == 0
,代表此分支已越过岛屿边界。搜索岛屿的同时,执行
grid[i][j] = '0'
,即将岛屿所有节点删除,以免之后重复搜索相同岛屿。
/*
1、c++11支持成员变量类内初始化,但是成员变量是数组时,必须指定大小!
2、这道题用到DFS算法,是我没有想到的。原本以为DFS只是用来遍历图,树。
其实DFS是一种广泛应用的搜索算法!需要好好感受!
(二刷发现这道题就是图的遍历,哈哈哈!)
*/
class Solution {
public:
//类内初始化数组必须指明数组大小
//int dx[] = {-1, 1, 0, 0}; 错误
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};
/*遍历整个矩阵,当遇到 grid[i][j] == '1' 时,
从此点开始做深度优先搜索 dfs,岛屿数 count + 1 且在深度优先搜索中删除此岛屿。
*/
int numIslands(vector<vector<char>>& grid) {
int islands = 0;
for (int i = 0; i < grid.size(); i++) {
for (int j = 0; j < grid[0].size(); j++) {
if (grid[i][j] == '1') {
sink(grid, i, j);
islands ++;
}
}
}
return islands;
}
//深度优先搜索
void sink(vector<vector<char>>& grid, int i, int j) {
if (i >= 0 && i < grid.size() && j >= 0 && j < grid[0].size() && grid[i][j] == '1') {
/*这一步相当关键
先把当前值设为1,可以保证没有往返下探!
*/
grid[i][j] = '0';
for (int k = 0; k < 4; k++) {
int x = i + dx[k];
int y = j + dy[k];
sink(grid, x, y);
}
}
}
};
class Solution {
public:
int numIslands(vector<vector<char>>& grid) {
int cnt = 0;
for (int i = 0; i < grid.size(); i++) {
for (int j = 0; j < grid[0].size(); j++) {
if (grid[i][j] == '1') {
sink(grid, i, j);
cnt++;
}
}
}
return cnt;
}
void sink(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';
sink(grid, i - 1, j);
sink(grid, i + 1, j);
sink(grid, i, j - 1);
sink(grid, i ,j + 1);
}
};
方法2、BFS
class Solution {
public:
int numIslands(vector<vector<char>>& grid) {
int cnt = 0;
for (int i = 0; i < grid.size(); i++) {
for (int j = 0; j < grid[0].size(); j++) {
if (grid[i][j] == '1') {
sink(grid, i, j);
cnt++;
}
}
}
return cnt;
}
void sink(vector<vector<char>> &grid, int i, int j) {
queue<pair<int, int>> que;
grid[i][j] = '0';
que.push(make_pair(i, j));
while (!que.empty()) {
auto tmp = que.front();
que.pop();
int i1 = tmp.first;
int j1 = tmp.second;
if (i1 - 1 >= 0 && grid[i1 - 1][j1] == '1') {
grid[i1 - 1][j1] = '0';
que.push(make_pair(i1 - 1, j1));
}
if (i1 + 1 < grid.size() && grid[i1 + 1][j1] == '1') {
grid[i1 + 1][j1] = '0';
que.push(make_pair(i1 + 1, j1));
}
if (j1 - 1 >= 0 && grid[i1][j1 - 1] == '1') {
grid[i1][j1 - 1] = '0';
que.push(make_pair(i1, j1 - 1));
}
if (j1 + 1 < grid[0].size() && grid[i1][j1 + 1] == '1') {
grid[i1][j1 + 1] = '0';
que.push(make_pair(i1, j1 + 1));
}
}
}
};