classSolution{ publicintminCostConnectPoints(int[][] points){ //结点的个数 int n = points.length; DisjointSetUnion dsu = new DisjointSetUnion(n); List<Edge> edges = new ArrayList<>(); //计算所有的边 for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { edges.add(new Edge(dist(points, i, j), i, j)); } } //按照边的大小由小到大排序 Collections.sort(edges, Comparator.comparingInt(edge -> edge.len)); int ret = 0, num = 1; //遍历所有的边 for (Edge edge : edges) { int len = edge.len, x = edge.x, y = edge.y; //判断两条边是否连通,即是否有同一个父节点,如果是直接跳过 //如果不是,则将边加入最小生成树,更新ret和num if (dsu.unionSet(x, y)) { ret += len; num++; if (num == n) { break; } } } return ret; }
//计算两点之间的曼哈顿距离 publicintdist(int[][] points, int x, int y){ return Math.abs(points[x][0] - points[y][0]) + Math.abs(points[x][1] - points[y][1]); } }
//并查集实现 classDisjointSetUnion{ int[] f; int[] rank; int n;
publicDisjointSetUnion(int n){ this.n = n; this.rank = newint[n]; Arrays.fill(this.rank, 1); this.f = newint[n]; for (int i = 0; i < n; i++) { this.f[i] = i; } }
//查 publicintfind(int x){ return f[x] == x ? x : (f[x] = find(f[x])); }
//并 publicbooleanunionSet(int x, int y){ int fx = find(x), fy = find(y); if (fx == fy) { returnfalse; }
if (rank[fx] < rank[fy]) { int temp = fx; fx = fy; fy = temp; }
rank[fx] += rank[fy]; f[fy] = fx; returntrue; } }
//定一个边,包括长度、起始点和终止点 classEdge{ int len, x, y;
publicEdge(int len, int x, int y){ this.len = len; this.x = x; this.y = y; } }