1.岛屿数量 深搜
99. 岛屿数量 | 代码随想录
代码:(在符合递归条件时进行递归处理)
#include <iostream>
#include <vector>
using namespace std;
int dir[4][2] = {1,0,0,1,-1,0,0,-1}; // 表示4个方向 上下左右
void dfs(const vector<vector<int>> &grid,vector<vector<bool>>&visited,int x,int y){
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;
}
if(!visited[nextx][nexty] && grid[nextx][nexty] == 1){ //没访问过的岛屿
visited[nextx][nexty] = true;
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(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){
visited[i][j] = true;
result++;
dfs(grid,visited,i,j);
}
}
}
// 输出
cout << result << endl;
}
代码:(在递归中用终止条件和处理逻辑)
#include <iostream>
#include <vector>
using namespace std;
int dir[4][2] = {1,0,0,1,-1,0,0,-1}; // 表示4个方向 上下左右
void dfs(const vector<vector<int>> &grid,vector<vector<bool>>&visited,int x,int y){
// 终止条件
if(visited[x][y] == true || grid[x][y] == 0) 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];
}
}
// 处理
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++;
dfs(grid,visited,i,j);
}
}
}
// 输出
cout << result << endl;
}
思路:
这道题的思路就是用visited数组来进行标记我们访问过的岛屿,每发现一个没有被标记过的岛屿就进行对岛屿个数的统计,并对其进行访问后的标记。
在代码1中,是在符合深搜条件的情况下进行深搜的调用,因为在调用前就已经判断了,所以把visited的标记直接在调用前就进行处理了。
在代码2中,是由深搜的终止条件来判断是不是要进行下面的代码。在深搜的开始就是判断是不是到了终止条件,如果没有,就可以进行visited的标记访问了。
2.岛屿深度 广搜
99. 岛屿数量 | 代码随想录
代码:
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
int dir[4][2] = {1,0,0,1,-1,0,0,-1}; // 表示4个方向 上下左右
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++;
bfs(grid,visited,i,j);
}
}
}
// 输出
cout << result << endl;
}
思路:
要注意,在元素加入对列时就进行标记,不然就会进行重复操作,导致超时。
深搜是进行递归操作。
广搜是利用一个数据结构来保存我们遍历过的结点,一般用的是对列。
将元素的下标存入队列中,然后标记为已访问。
然后就是从这个结点出发,去把它四周的岛屿结点都标记为已访问(因为这些都只算作一个岛屿) ,我们用的是for循环,将此节点出栈,遍历它四个方向的相邻结点,遇到满足要求的(未访问且是岛屿结点),就将其入栈,并且立刻标记为已经访问。
3.岛屿的最大面积
100. 岛屿的最大面积 | 代码随想录
代码:dfs(满足深搜条件时,再进行深搜)
#include <iostream>
#include <vector>
using namespace std;
int count;
int dir[4][2] = {1,0,0,1,-1,0,0,-1};
void dfs(const vector<vector<int>>&grid,vector<vector<bool>>&visited,int x,int y){
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;
}
if(!visited[nextx][nexty] && grid[nextx][nexty] == 1){
visited[nextx][nexty] = true;
count++;
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){
count = 1;
visited[i][j]=true;
dfs(grid,visited,i,j);
result = max(count,result);
}
}
}
// 输出
cout << result << endl;
}
代码:dfs(用终止条件)
#include <iostream>
#include <vector>
using namespace std;
int count;
int dir[4][2] = {1,0,0,1,-1,0,0,-1};
void dfs(const 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];
}
}
// 处理
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++){
count = 0;
dfs(grid,visited,i,j);
result = max(count,result);
}
}
// 输出
cout << result << endl;
}
代码: bfs
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
int count;
int dir[4][2] = {1,0,0,1,-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;
count++;
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;
count++;
}
}
}
}
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){
count = 0;
bfs(grid,visited,i,j);
result = max(count,result);
}
}
}
// 输出
cout << result << endl;
}
思路:这道题就是在进行visited标记的适合,下一步就对本次循环的访问结点进行计数,count++。这里巧妙地在main函数里的第二次for循环里将count先置为0。然后调用深搜或广搜的适合,从0开始技术,就可以达到求出来的是一个岛屿的面积。用result来记录这些岛屿面积的最大值,然后输出即可。