岛屿问题
(200)岛屿的数量
本题是利用DFS遍历二维矩阵解决岛屿问题的基本问题,后面的岛屿问题都是基于此题的代码,在主函数中进行少量的逻辑修改。
0表示水,1表示陆地
覆盖以{i,j}开始的路地。
void DFS(vector<vector<int>>& grid,int x,int y){
if(x<0||x>=grid.size()||y<0||y>=grid[0].size()||grid[x][y]==0) return;
grid[x][y]=0; //将走过的路地全部修改为水,避免维护visited数组。
DFS(grid,x-1,y);
DFS(grid,x+1,y);
DFS(grid,x,y+1);
DFS(grid,x,y-1);
}
int solve(vector<vector<int>>& grid){
int m=grid.size();
int n=grid[0].size();
int res=0;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(grid[i][j]==1){
res++;
DFS(grid,i,j);
}
}
}
}
(695) 岛屿的最大面积
本题是在200的基础上求所有岛屿的面积,在利用DFS函数淹没岛屿的同时需要记录这个岛屿的面积。可以给DFS设置返回值,记录每次淹没岛屿的数量;
int DFS(vector<vector<int>>& grid,int x,int y){
if(x<0||x>=grid.size()||y<0||y>=grid[0].size()||grid[x][y]==0) return;
grid[x][y]=0; //将走过的路地全部修改为水,避免维护visited数组。
return DFS(grid,x-1,y)+DFS(grid,x+1,y)+DFS(grid,x,y+1)+DFS(grid,x,y-1)+1;
}
int solve(vector<vector<int>>& grid){
int m=grid.size();
int n=grid[0].size();
int res=0;
int maxarea=0;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(grid[i][j]==1){
res=resDFS(grid,i,j);
maxarea=max(maxarea,res);
}
}
}
}
(130)被围绕的区域
本题是利用DFS将“O”改成“X”,不包含边界的“O”。在这里用到了一个小技巧就是将边界的“O”改成第三个字符“A”(或者其他),然后按照200中的遍历去判断,当遇到“A”说明是边界,将“A”在修改为“O”,遇到“O”则修改为“X”。
void dfs(vector<vector<char>>& board, int x, int y) {
if (x < 0 || x >= n || y < 0 || y >= m || board[x][y] != 'O') {
return;
}
board[x][y] = 'A';
dfs(board, x + 1, y);
dfs(board, x - 1, y);
dfs(board, x, y + 1);
dfs(board, x, y - 1);
}
void solve(vector<vector<char>>& board) {
n = board.size();
if (n == 0) {
return;
}
m = board[0].size();
for (int i = 0; i < n; i++) {
dfs(board, i, 0);
dfs(board, i, m - 1);
}
for (int i = 1; i < m - 1; i++) {
dfs(board, 0, i);
dfs(board, n - 1, i);
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (board[i][j] == 'A') {
board[i][j] = 'O';
} else if (board[i][j] == 'O') {
board[i][j] = 'X';
}
}
}
}
(1254)统计封闭岛屿的数量
本题是在200之上,将边界的岛屿全部排除掉,剩下的就是封闭的岛屿,如何将边界的岛屿排除掉呢,就是利用DFS来修改边界的岛屿。
void DFS(vector<vector<int>>& grid,int x,int y){
if(x<0||x>=grid.size()||y<0||y>=grid[0].size()||grid[x][y]==0) return;
grid[x][y]=0; //将走过的路地全部修改为水,避免维护visited数组。
DFS(grid,x-1,y);
DFS(grid,x+1,y);
DFS(grid,x,y+1);
DFS(grid,x,y-1);
}
int solve(vector<vector<int>>& grid){
int m=grid.size();
int n=grid[0].size();
for(int j=0;j<n;j++){
DFS(grid,0,j);
DFS(grid,m-1,j);
}
for(int i=0;i<m;i++){
DFS(grid,i,0);
DFS(grid,i,n-1);
}
int res=0;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(grid[i][j]==0){
res++;
DFS(grid,i,j);
}
}
}
}
(1905)统计子岛屿
本题两个岛屿,gird1和grid2,判断grid2中有多少岛屿是grid1的子岛屿。可以这样思考,如果grid1中的一个位置为0,那么grid2对应位置的岛屿肯定不是之岛屿。
void DFS(vector<vector<int>>& grid2,int x,int y){
if(x<0||x>=grid2.size()||y<0||y>=grid2[0].size()||grid2[x][y]==0) return;
grid2[x][y]=0;
DFS(grid2,x+1,y);
DFS(grid2,x-1,y);
DFS(grid2,x,y+1);
DFS(grid2,x,y-1);
}
int countSubIslands(vector<vector<int>>& grid1, vector<vector<int>>& grid2) {
int m=grid1.size();
int n=grid1[0].size();
//排除掉grid中为0,
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(grid1[i][j]==0&&grid2[i][j]==1)
DFS(grid2,i,j);
}
}
int res=0;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(grid2[i][j]==1)
{
res++;
DFS(grid2,i,j);
}
}
}
return res;
(694)不同岛屿的数量
在本题中,需要将路径序列化,上(u)、下(d)、左(L)、右®利用字符标记,然后利用set来去重。
DFS的记忆化搜索
329. 矩阵中的最长递增路径
在DFS搜索中,将每个位置的信息保存下里,