链表类型的数组
1.使用场景
如上面的leetcode题目所是,题目给出来的是用二维数组表示的图,这样表示的图,不利有我们解题目,所以我们需要用另外的数据结构将图给存储起来。在本文中介绍图的拉链法:就是定义一个数组,但是这个数组的是链表类型,把所有和该数组节点连接的节点挂在该数组对应index指向的链表(具体可以看下面的代码)
class Solution {
public long countPairs(int n, int[][] edges) {
List<Integer>[] g = new ArrayList[n];
Arrays.setAll(g, e -> new ArrayList<>());
for(int[] e : edges){
int x = e[0], y = e[1];
g[x].add(y);
g[y].add(x);//建图
}
boolean[] vis = new boolean[n];
long ans = 0;
for(int i = 0, total = 0; i < n; i++){
if(!vis[i]){//未访问的点,说明找到了一个新的连通块
int size = dfs(i, g, vis);
ans += (long)size * total;
total += size;
}
}
return ans;
}
//递归调用
public int dfs(int x , List<Integer>[] g, boolean[] vis){
vis[x] = true; //避免重复访问同一个点
int size = 1;
for(int y : g[x]){
if(!vis[y]){
size += dfs(y, g, vis);
}
}
return size;
}
}
2.注意区别Arrays下的setAll和fill
链表类型的数组的初始化如下所是,一定要注意使用的是setAll方法不是fill方法:
List<Integer>[] arr = new ArrayList[nums.length];
Arrays.setAll(arr,e -> new ArrayList<>());
我最开始建图的时候,因为弄混setAll和fill方法,也就是下面的错误写法:只初始化了一个链表,并且让所有的数组的index指向该链表(是错误的)。我们需要的是为数组的每一个空间都初始化一个链表,链表用来连接与该空间节点相连的节点值。
List<Integer>[] arr = new ArrayList[nums.length];
Arrays.fill(arr,new ArrayList<>());