leedcode-并查集

并查集实现

  • parent:记录每个节点的父节点
  • size:记录每棵树的重量,目的是 union 后树依然保持平衡性
  • 路径压缩:保证任意数的高度为常数
public class UF {
	 // 连通分量个数
	 private int count;
	 // 存储一个树
	 private int[] parent;
	 // 记录树的重量(将小一些的树接到大一些的树下面)
	 private int[] size;

	 public UF(int n) {
		  this.count = n;
		  // 最初每棵树只有一个节点
		  // 重量初始化为 1
		  parent = new int[n];
		  size = new int[n];
		  for(int i = 0; i < n; i++) {
			   parent[i] = i;
			   size[i] = 1;
		  }
	 }

	 // 寻找父节点
	 private int find(int x) {
		  while(parent[x] != x) {
			   // 路径压缩(父节点改为根节点)
			   parent[x] = parent[parent[x]];
			   x = parent[x];
		  }
		  return x;
	 }

	 // 合并
	 public void union(int p, int q) {
		  int rootP = find(p);
		  int rootQ = find(q);
		  if(rootP == rootQ) {
			   return;
		  }
  
		  // 小树接到大树下面
		  if(size[rootP] > size[rootQ]) {
			   parent[rootQ] = rootP;
			   size[rootP] += size[rootQ];
		  }else {
			   parent[rootP] = rootQ;
			   size[rootQ] += size[rootP];
		  }
  
		  count--;
	 }
 
	  // 二者是否连通
	 public boolean connected(int p, int q) {
		  int rootP = find(p);
		  int rootQ = find(q);
		  return rootP == rootQ;
	 }
 
	 public int count() {
		  return count;
	 }
}	 

应用

  1. 等式方程的可满足性(leedcode-990)
    public boolean equationsPossible(String[] equations) {
	     UF uf = new UF(26);
     
	     for(String s : equations) {
		      if(s.charAt(1) == '=') {
			       uf.union(s.charAt(0) - 'a', s.charAt(3) - 'a');
		      }
	     }
	     for(String s : equations) {
		      if(s.charAt(1) == '!') {
			       if(uf.connected(s.charAt(0) - 'a', s.charAt(3) - 'a')) {
				        return false;
			       }
		      }
	     }
     
     
	     return true;
  }   

你可能感兴趣的:(Java)