三、DFS练习题
2)
力扣https://leetcode.cn/problems/number-of-provinces/submissions/这题与前一篇博客中计算岛屿面积类似,只是换成了计算省份数量,以及搜索范围扩大到所有城市了。
利用深度优先搜索算法,依次遍历每个未访问的城市,若该城市与其他未访问城市A相连,则继续向下访问城市A,若城市A与未访问城市B相连,则访问城市B,若城市B……
用递归来写,代码也十分简洁:
class Solution {
public:
int findCircleNum(vector<vector<int>>& isConnected) {
int n = isConnected.size();
vector<bool> visited(n,false);
int res = 0;
for(int i=0;i<n;i++){
if(!visited[i]){
res++;
dfs(isConnected,i,visited);
}
}
return res;
}
void dfs(vector<vector<int>>& isConnected, int x, vector<bool>& visited){
visited[x] = true;
int n = isConnected.size();
for(int i=0;i<n;i++){
if(i!=x && isConnected[x][i]==1 && !visited[i]){
dfs(isConnected,i,visited);
}
}
}
};
3)
力扣https://leetcode.cn/problems/pacific-atlantic-water-flow/这道题如果对每个坐标进行深度优先搜索,就会十分复杂,O(N^2)。
所以可以反向思考,从四条边出发进行深搜,判断是否满足大于等于的条件。
class Solution {
public:
vector<vector<int>> pacificAtlantic(vector<vector<int>>& heights) {
vector<vector<int>> res;
int m = heights.size();
if(m==0) return res;
int n = heights[0].size();
if(n==0) return res;
vector<vector<bool>> pac(m, vector<bool>(n,false));
vector<vector<bool>> atl(m, vector<bool>(n,false));
for(int i=0;i<m;i++){
dfs(heights,pac,i,0);
dfs(heights,atl,i,n-1);
}
for(int i=0;i<n;i++){
dfs(heights,pac,0,i);
dfs(heights,atl,m-1,i);
}
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(pac[i][j] && atl[i][j]){
res.push_back({i,j});
}
}
}
return res;
}
void dfs(vector<vector<int>>& heights, vector<vector<bool>>& visit, int x, int y ){
if(visit[x][y]) return;
visit[x][y] = true;
for(int i=0;i<4;i++){
int a = x + p[i];
int b = y + q[i];
if(a>=0 && b>=0 && a<heights.size() && b<heights[0].size()&&
heights[x][y]<=heights[a][b]
){
dfs(heights,visit,a,b);
}
}
}
private:
vector<int> p = {0,0,-1,1};
vector<int> q = {-1,1,0,0};
};