python實現:約瑟夫環
阿新 • • 發佈:2021-01-24
技術標籤:演算法
- 連通網路的操作次數
用乙太網線纜將 n 臺計算機連線成一個網路,計算機的編號從 0 到 n-1。線纜用 connections 表示,其中 connections[i] = [a, b] 連線了計算機 a 和 b。
網路中的任何一臺計算機都可以通過網路直接或者間接訪問同一個網路中其他任意一臺計算機。
給你這個計算機網路的初始佈線 connections,你可以拔開任意兩臺直連計算機之間的線纜,並用它連線一對未直連的計算機。請你計算並返回使所有計算機都連通所需的最少操作次數。如果不可能,則返回 -1 。
示例 1:
輸入:n = 4, connections = [[0,1],[0,2],[1,2]]輸出:1
解釋:拔下計算機 1 和 2 之間的線纜,並將它插到計算機 1 和 3 上。
示例 2:
輸入:n = 6, connections = [[0,1],[0,2],[0,3],[1,2],[1,3]]
輸出:2
示例 3:
輸入:n = 6, connections = [[0,1],[0,2],[0,3],[1,2]]
輸出:-1
解釋:線纜數量不足。
示例 4:
輸入:n = 5, connections = [[0,1],[0,2],[3,4],[2,3]]
輸出:0
class Solution {
public int makeConnected(int n, int[][] connections) {
if (connections.length < n - 1) {
return -1;
}
UnionFind uf = new UnionFind(n);
for (int[] conn : connections) {
uf.unite(conn[0], conn[1]);
}
return uf.setCount - 1;
}
}
// 並查集模板
class UnionFind {
int[] parent;
int [] size;
int n;
// 當前連通分量數目
int setCount;
public UnionFind(int n) {
this.n = n;
this.setCount = n;
this.parent = new int[n];
this.size = new int[n];
Arrays.fill(size, 1);
for (int i = 0; i < n; ++i) {
parent[i] = i;
}
}
public int findset(int x) {
return parent[x] == x ? x : (parent[x] = findset(parent[x]));
}
public boolean unite(int x, int y) {
x = findset(x);
y = findset(y);
if (x == y) {
return false;
}
if (size[x] < size[y]) {
int temp = x;
x = y;
y = temp;
}
parent[y] = x;
size[x] += size[y];
--setCount;
return true;
}
public boolean connected(int x, int y) {
x = findset(x);
y = findset(y);
return x == y;
}
}
作者:LeetCode-Solution
連結:https://leetcode-cn.com/problems/number-of-operations-to-make-network-connected/solution/lian-tong-wang-luo-de-cao-zuo-ci-shu-by-leetcode-s/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。
雖然看到並查集內心沒有絲毫波瀾,但是我發現自己看的多了發現自己的瞭解更為深刻,所以雖然近幾天沒有敲程式碼的心思,但是自己又閒得無聊,所以還是搞一搞!上面是官方的解釋,下面是大佬做的。
public int makeConnected(int n, int[][] connections) {
if (connections.length < n - 1) return -1;
int size[] = new int[n];
int parent[] = new int[n];
count = n;
for (int i = 0; i < n; i++) {
size[i] = 1;
parent[i] = i;
}
for (int[] connection : connections) {
int x = connection[0];
int y = connection[1];
union(x, y, parent, size);
}
return --count;
}
int count;
private void union(int x, int y, int parent[], int size[]) {
int fx = find(x, parent);
int fy = find(y, parent);
if (fx == fy) {
return;
} else {
if (size[fx] >= size[fy]) {
parent[fy] = fx;
size[fx] += size[fy];
} else {
parent[fx] = fy;
size[fy] += size[fx];
}
count--;
}
}
private int find(int x, int parent[]) {
if (parent[x] != x) {
int father = find(parent[x], parent);
parent[x] = father;
}
return parent[x];
}
}
這裡說一下大佬的思路,根據題目給出的陣列值,將連通分量合併,每合併一次,cnt(記錄的多餘的連線線的數值)相應的減一,最後返回相應的cnt-1(cnt初始值設為n)。