前言
###我做这类文章一个重要的目的还是给正在学习的大家提供方向和记录学习过程(例如想要掌握基础用法,该刷哪些题?)我的解析也不会做的非常详细,只会提供思路和一些关键点,力扣上的大佬们的题解质量是非常非常高滴!!!
习题
1.统计完全连通分量的数量
题目链接: 2685. 统计完全连通分量的数量 - 力扣(LeetCode)
题面:
分析:我的做法是通过并查集来确定哪些节点是连在一起的,然后通过集合数组来判断连在一起的节点是否互相都存在路
代码:
java
class Solution {
int[] parent;
int ans = 0;
List<Integer>[] to;
int n;
public int countCompleteComponents(int n, int[][] edges) {
this.n = n;
parent = new int[n];
for(int i = 0;i<n;i++){
parent[i] = i;
}
to = new List[n];
Arrays.setAll(to,_->new ArrayList<>());
for(int[] arr:edges){
int a = arr[0];
int b = arr[1];
union(a,b);
to[a].add(b);
to[b].add(a);
}
Map<Integer,Integer> map = new HashMap<>();
for(int i = 0;i<n;i++){
if(map.getOrDefault(find(i),-1)==-1){
map.put(find(i),1);
recursion(find(i));
}
}
return ans;
}
public void recursion(int parent){
int[] arr = new int[n];
int count = 0;
for(int i = 0;i<n;i++){
if(find(i)==parent){
arr[count++] = i;
// System.out.println(i);
}
}
if(count==1){
ans++;
return;
}
for(int i = 0;i<count-1;i++){
for(int j = i+1;j<count;j++){
if(!isHave(arr[i],arr[j])){
return;
}
}
}
ans++;
}
public boolean isHave(int x,int y){
for(int a:to[x]){
if(a==y)return true;
}
return false;
}
public int find(int x){
if(parent[x]!=x){
parent[x] = find(parent[x]);
}
return parent[x];
}
public void union(int a,int b){
int pa = find(a);
int pb = find(b);
if(pa!=pb){
parent[pa]=pb;
}
}
public boolean isInALine(int a,int b){
return find(a)==find(b);
}
}
2.有向无环图中的一个节点的所有祖先
题目链接: 2192. 有向无环图中一个节点的所有祖先 - 力扣(LeetCode)
题面:
分析:我的思路是利用集合数组在遍历edges存储表示节点i可被节点j到达,然后使用递归来找祖先节点,例如beto[1] = {2,3}表示节点1可以被节点2,3到达,那么我们把2,3存入Treeset集合,然后递归找2,3可以被哪些节点到达......,Treeset可以自动去重和排序,但是亲测复杂度很高
java
class Solution {
List<List<Integer>> ans = new ArrayList<>();
List<Integer>[] beto;
public List<List<Integer>> getAncestors(int n, int[][] edges) {
beto = new List[n];
Arrays.setAll(beto,_->new ArrayList<>());
for(int[] arr:edges){
beto[arr[1]].add(arr[0]);
}
TreeSet<Integer> set;
for(int i = 0;i<n;i++){
set = new TreeSet<>();
recursion(i,set);
ans.add(new ArrayList<>(set));
}
return ans;
}
public void recursion(int x,TreeSet<Integer> set){
for(int a:beto[x]){
if(!set.contains(a)){
set.add(a);
recursion(a,set);
}
}
}
}
后言
上面是力扣图论专题,下一篇是其他的习题,希望有所帮助,一同进步,共勉!