并查集 + DFS
并查集的作用就是维护某种类型的群体:相隔的群体,(1,3,7,9)(2,8)(4,6)
DFS的作用就是列举出各种情况 ,深度的遍历。在列举的过程中,也要根据题意进行判断。
public class test {
private WeightedUnionFind wuf = new WeightedUnionFind(10);
private int res;
public int numberOfPatterns(int m, int n){
wuf.union(1,3);
wuf.union(1,7);
wuf.union(1,9);
wuf.union(2,8);
wuf.union(4,6);
boolean[] visited = new boolean[];
for(int i=1; i<=9; i++){
dfs(i,1,visited,m,n);
}
return res;
}
private void dfs(int curKey, int keyNum, boolean[] visited, int m, int n){
if(keyNum>=m && keyNum<=n){
res++;
}else if(keyNum > n){
return;
}
visited[curKey] = true;
for(int i=1; i<=9; i++){
boolean cross = wuf.connected(i, curKey);
if(!visited[i] && (!cross || visited[(curKey + i) / 2])){
dfs(i, keyNum+1, visited, m, n);
}
}
visited[curKey] = false;
}
}
class WeightedUnionFind{
int[] id;
int[] sz;
public WeightedUnionFind(int N){
id = new int[N];
sz = new int[N];
for(int i = 0; i<N; i++){
id[i] = i;
sz[i] = 1;
}
}
public void union(int p, int q){
int pRoot = find(p);
int qRoot = find(q);
if(pRoot == qRoot){
return;
}
if(sz[pRoot] > sz[qRoot]){
sz[pRoot] += sz[qRoot];
id[qRoot] = id[pRoot];
}else{
sz[qRoot] += sz[pRoot];
id[pRoot] = id[qRoot];
}
}
public boolean connected(int p, int q){
return find(p) == find(q);
}
public int find(int p){
while(p != id[p]){
id[p] = id[id[p]];
p = id[p];
}
return p;
}
}