概念TODO
UF的標準模板
算法實戰
- 等式方程的可滿足性(medium)
- 朋友圈(medium)
- 最長連續序列(hard)
下面將介紹以上題目的實現:
等式方程的可滿足性(medium)
分析:
- List item
class Solution {
public boolean equationsPossible(String[] equations) {
int n = equations.length;
UF uf = new UF();
for (int i = 0; i < n; i++) {
if (equations[i].charAt(1) == '='){
uf.union(equations[i].charAt(0) - 'a', equations[i].charAt(3) - 'a');
}
}
for (int i = 0; i < n; i++) {
if (equations[i].charAt(1) == '=' && !uf.connected(equations[i].charAt(0) - 'a', equations[i].charAt(3) - 'a') ){
return false;
}
if (equations[i].charAt(1) == '!' && uf.connected(equations[i].charAt(0) - 'a', equations[i].charAt(3) - 'a') ){
return false;
}
}
return true;
}
class UF {
int[] id;
int[] size;
public UF() {
id = new int[26];
size = new int[26];
for (int i = 0; i < 26; i++){
id[i] = i;
size[i] = 1;
}
}
public int find(int p){
while (p != id[p]) {
id[p] = id[id[p]];
p = id[p];
}
return p;
}
public void union(int p, int q) {
int pRoot = find(p);
int qRoot = find(q);
if (pRoot == qRoot) return;
if (size[pRoot] < size[qRoot]){
id[pRoot] = qRoot;
size[qRoot] += size[pRoot];
}else {
id[qRoot] = pRoot;
size[pRoot] += size[qRoot];
}
}
public boolean connected(int p, int q) {
return find(p) == find(q);
}
}
}
執行用時 :1 ms, 在所有 Java 提交中擊敗了100.00%的用戶
內存消耗 :39.3 MB, 在所有 Java 提交中擊敗了16.67%的用戶
- 547 朋友圈(medium)
班上有 N 名學生。其中有些人是朋友,有些則不是。他們的友誼具有是傳遞性。如果已知 A 是 B 的朋友,B 是 C 的朋友,那麼我們可以認爲 A 也是 C 的朋友。所謂的朋友圈,是指所有朋友的集合。
給定一個 N * N 的矩陣 M,表示班級中學生之間的朋友關係。如果M[i][j] = 1,表示已知第 i 個和 j
個學生互爲朋友關係,否則爲不知道。你必須輸出所有學生中的已知的朋友圈總數。示例 1:
輸入: [[1,1,0], [1,1,0], [0,0,1]] 輸出: 2 說明:已知學生0和學生1互爲朋友,他們在一個朋友圈。
第2個學生自己在一個朋友圈。所以返回2
class Solution {
//Union Find
public int findCircleNum(int[][] M) {
int n = M.length;
UF uf = new UF(n);
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) {
if (M[i][j] == 1)
uf.union(i, j);
}
return uf.count;
}
class UF {
int[] id;
int[] size;
public int count;
public UF(int n) {
id = new int[n];
size = new int[n];
count = n;
for (int i = 0; i < n; i++) {
id[i] = i;
size[i] = 1;
}
}
public int find(int p) {
while (p != id[p]) {
id[p] = id[id[p]];
p = id[p];
}
return p;
}
public void union(int p, int q) {
int pRoot = find(p);
int qRoot = find(q);
if (pRoot == qRoot) return;
if (size[pRoot] < size[qRoot]) {
id[pRoot] = qRoot;
size[qRoot] += size[pRoot];
count--;
} else {
id[qRoot] = pRoot;
size[pRoot] += size[qRoot];
count--;
}
}
}
DFS解法:
public int findCircleNum(int[][] M) {
int m = M.length;
int count = 0;
int[] visited = new int[m]; //all 0
for (int i = 0; i < m; i++)
if (visited[i] == 0){
dfs(M, i, visited);
count++;
}
return count;
}
public void dfs(int[][] M, int i, int[] visited) {
for (int j = 0; j < M.length; j++){
if (visited[j] == 0 && M[i][j] == 1){
visited[j] = 1;
dfs(M, j, visited);
}
}
}