这个系列放在leetcode上刷到用DFS解的题,不断扩充,我自己遇到就会加进来。
题目均来自leetcode,括号内是题目标号
1. Number of Islands(200)
Given a 2d grid map of ‘1’s (land) and ‘0’s (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.
Example 1:
Input:
11110
11010
11000
00000
Output: 1
Example 2:
Input:
11000
11000
00100
00011
Output: 3
题目大意:‘1’表示陆地,‘0’是海洋,求出图中相连的陆地的数目
解题思路:找到图中值为1的点,分别从上、下、左、右四个方向搜索,搜索过的‘1’就置为‘0’,每完成一整片陆地的搜索,计数器加一
代码如下:
class Solution {
public:
int numIslands(vector<vector<char>>& grid) {
int count = 0;
for(int i = 0; i < grid.size(); i++ ){
for(int j =0 ; j < grid[i].size(); j++){
if(grid[i][j] == '1'){
dfs(i,j, grid);
++count;
}
}
}
// cout<<"count = "<<count<<endl;
return count;
}
private:
void dfs(int x,int y, vector<vector<char>>& grid){
if(x < 0 || x >= grid.size() || y < 0 || y >= grid[0].size() || grid[x][y] == '0')
return;
grid[x][y] = '0';
dfs(x+1, y, grid);
dfs(x-1, y, grid);
dfs(x, y+1, grid);
dfs(x, y-1, grid);
}
};
一个坑:写完之后测试样例,发现结果始终为0,代码就没有执行++count这句,就一脸蒙蔽不知道哪出了问题,后来才发现grid[x][y] = ‘1’这句没加引号,真是服了我自己惹。
2.Max Area of Island(695)
Given a non-empty 2D array grid of 0’s and 1’s, an island is a group of 1’s (representing land) connected 4-directionally (horizontal or vertical.) You may assume all four edges of the grid are surrounded by water.
Find the maximum area of an island in the given 2D array. (If there is no island, the maximum area is 0.)
Example 1:
[[0,0,1,0,0,0,0,1,0,0,0,0,0],
[0,0,0,0,0,0,0,1,1,1,0,0,0],
[0,1,1,0,1,0,0,0,0,0,0,0,0],
[0,1,0,0,1,1,0,0,1,0,1,0,0],
[0,1,0,0,1,1,0,0,1,1,1,0,0],
[0,0,0,0,0,0,0,0,0,0,1,0,0],
[0,0,0,0,0,0,0,1,1,1,0,0,0],
[0,0,0,0,0,0,0,1,1,0,0,0,0]]
Given the above grid, return 6. Note the answer is not 11, because the island must be connected 4-directionally.
Example 2:
[[0,0,0,0,0,0,0,0]]
Given the above grid, return 0.
Note: The length of each dimension in the given grid does not exceed 50.
题目大意:1表示岛屿,上下左右四个方向可达,求拥有最大数目的联通岛屿
解题思路:从地图中值为1的位置遍历地图,每个搜索过的位置都将1置为0,分别找出上、下、左、右四个方向每个方向的岛屿数目,将它们加起来,再加上1(表示搜索起点位置的岛屿)即为所求。
代码如下:
class Solution {
public:
int maxAreaOfIsland(vector<vector<int>>& grid) {
int count = 0;
for(int i = 0; i < grid.size(); i++ ){
for(int j =0 ; j < grid[i].size(); j++){
if(grid[i][j] == 1){
count = dfs(i,j, grid);
if(count > m)
m = count;
}
}
}
// cout<<"count = "<<count<<endl;
// return count;
return m;
}
private:
int m = 0;
int dfs(int x,int y, vector<vector<int>>& grid){
if(x < 0 || x >= grid.size() || y < 0 || y >= grid[0].size() || grid[x][y] != 1)
return 0;
grid[x][y] = 0;
return 1+dfs(x-1, y, grid)+dfs(x+1, y, grid)+dfs(x, y-1, grid)+dfs(x, y+1, grid);
}
};
3.Island Perimeter(463)
You are given a map in form of a two-dimensional integer grid where 1 represents land and 0 represents water. Grid cells are connected horizontally/vertically (not diagonally). The grid is completely surrounded by water, and there is exactly one island (i.e., one or more connected land cells). The island doesn’t have “lakes” (water inside that isn’t connected to the water around the island). One cell is a square with side length 1. The grid is rectangular, width and height don’t exceed 100. Determine the perimeter of the island.
Example:
[[0,1,0,0],
[1,1,1,0],
[0,1,0,0],
[1,1,0,0]]
Answer: 16
Explanation: The perimeter is the 16 yellow stripes in the image below:
题目大意:二维地图,每个单元格的长度为1的方形。1代表陆地,0代表水,上、下、左、右四个方向的单元格相连,求出相连陆地单元格的周长。
解题思路:看见题目tag是dfs,就想当然dfs+vis,结果超时,又读了下题,发现题目说只!有!一!块!大!陆!所以就不用dfs了,直接遍历地图,记录每个值为1的点的上下左右(注意边界)单元格的值是否为0,如果为0,计数器就加1。
class Solution {
public:
int islandPerimeter(vector<vector<int>>& grid) {
int ret=0;
int row=grid.size(),col=grid[0].size();
for(int i=0;i<row;i++)
for(int j=0;j<col;j++)
{
if(grid[i][j]==0)
continue;
if(i==0||grid[i-1][j]==0)ret++;
if(i==row-1||grid[i+1][j]==0) ret++;
if(j==0||grid[i][j-1]==0) ret++;
if(j==col-1||grid[i][j+1]==0) ret++;
}
return ret;
}
};