1.并查集
将给定双向图中的连通分量看成一个集合,把所有相连节点合并为一个集合,最后直接查找start和end节点的祖宗节点,若在同一集合内则说明存在从顶点start到end的路径
class Solution {
public:
static const int maxn=1e5;
int *fa=new int[maxn*2+10];
int find(int x){
if(fa[x]==x)return x;
else fa[x]=find(fa[x]);//这一步是重点!!!
return fa[x];
}
void merge(int i,int j){
int fa_i=find(i);
int fa_j=find(j);
fa[fa_i]=fa_j;
}
bool validPath(int n, vector<vector<int>>& edges, int source, int destination) {
for(int i=0;i<n;++i)fa[i]=i;
for(int i=0;i<edges.size();++i){
//for(int j=0;j<edges[i].size();++j){
merge(edges[i][0],edges[i][1]);
//}
}
int fa_i=find(source);
int fa_j=find(destination);
//fa[fa_i]=fa_j;
if(fa_j==fa_i)return 1;
return 0;
}
};
2.BFS(其实就是走迷宫的做法),时间复杂度O(N)
注意不要一开始就将vector初始化为n*n大小,这样会导致在执行队列内的代码:寻找当前节点的相邻节点的时间复杂度大大增加。
vector<int>v(n)和vector<int>v[n]区别:(n)表示开辟了n个空间,[n]表示创建了n个容器,二维的vector类似
class Solution {
public:
vector<int>vis;
bool validPath(int n, vector<vector<int>>& edges, int source, int destination) {
if(edges.empty())return 1;
int len=edges.size();
vector<vector<int>>mp(n);
//vector<vector<int>>vis(n,vector<int>(n,0));
vis.resize(n);
for(int i=0;i<edges.size();++i){
mp[edges[i][0]].push_back(edges[i][1]);
mp[edges[i][1]].push_back(edges[i][0]);
}
queue<int>q;
q.push(source);
//vis[source]=1;
while(!q.empty()){
int now=q.front();q.pop();
vis[now]=1;
if(now==destination)return 1;
for(int i=0;i<mp[now].size();++i){
if(vis[mp[now][i]]==0){
q.push(mp[now][i]);
}
}
}
return 0;
}
};
3.DFS
class Solution {
public:
vector<int>vis;
int flag=0;
void dfs(vector<vector<int>>& mp, int start, int end){
if(start==end){
flag=1;
return;
}
vis[start]=1;
for(int i=0;i<mp[start].size();++i){
if(!vis[mp[start][i]]){
dfs(mp,mp[start][i],end);
}
}
//return 0;
}
bool validPath(int n, vector<vector<int>>& edges, int source, int destination) {
if(edges.empty())return 1;
vector<vector<int>>mp(n);
vis.resize(n);
for(int i=0;i<edges.size();++i){
mp[edges[i][0]].push_back(edges[i][1]);
mp[edges[i][1]].push_back(edges[i][0]);
}
dfs(mp,source,destination);
if(flag)return 1;
return 0;
}
};