Amazonは本を販売している、すべての本は強く、それに関連付けられている本を持っています。LISTAとListBのを考えると、それを示している ListA [i]
に関連付けられている ListB [i]
書籍や関連図書を表しています。出力相互に関連付けられている最大のセット(任意の並べ替えで出力)。あなただけの最大のセットのうちの1つが存在すると仮定することができます。
例
Example 1:
Input: ListA = ["abc","abc","abc"], ListB = ["bcd","acd","def"]
Output: ["abc","acd","bcd","def"]
Explanation:
abc is associated with bcd, acd, dfe, so the largest set is the set of all books
Example 2:
Input: ListA = ["a","b","d","e","f"], ListB = ["b","c","e","g","g"]
Output: ["d","e","f","g"]
Explanation:
The current set are [a, b, c] and [d, e, g, f], then the largest set is [d, e, g, f]
通知
- 本の数は超えていません
5000
。
アイデア:本はノードで、<文字列、整数>マッピングの確立、持っていたハッシュマップは、追加していないならば、ノートのサイズは、別のインデックスと異なる本を表し、2 *であるnは、同じ本です。労働組合が完成その後、再びそれをスキャンし、最大のインデックスの最大サイズを見つけ、その後、インデックスに応じてタイトルを収集し、注意を払うの重みに、私は再びタイトルをスキャンしたため、タイトルの繰り返しがあり、あなたが繰り返さなければなりません。
public class Solution {
/**
* @param ListA: The relation between ListB's books
* @param ListB: The relation between ListA's books
* @return: The answer
*/
private class UnionFind {
private int[] father;
private int[] size;
public UnionFind(int n) {
father = new int[n+1];
size = new int[n+1];
for(int i = 0; i <= n; i++) {
father[i] = i;
size[i] = 1;
}
}
public int find(int x) {
int j = x;
while(father[j] != j) {
j = father[j];
}
// path compression;
while(x != j) {
int fx = father[x];
father[x] = j;
x = fx;
}
return j;
}
public void union(int a, int b) {
int root_a = find(a);
int root_b = find(b);
if(root_a != root_b) {
father[root_a] = root_b;
size[root_b] += size[root_a];
}
}
public int getSize(int index){
return this.size[index];
}
}
public List<String> maximumAssociationSet(String[] ListA, String[] ListB) {
List<String> result = new ArrayList<String>();
if(ListA == null || ListA.length == 0 || ListB == null || ListB.length == 0) {
return result;
}
int n = ListA.length;
// 注意这是两倍的size;
UnionFind uf = new UnionFind(2*n);
// 只用一个map就可以建立mapping;
HashMap<String, Integer> map = new HashMap<String, Integer>();
for(int i = 0; i < ListA.length; i++) {
if(!map.containsKey(ListA[i])){
map.put(ListA[i], i);
}
if(!map.containsKey(ListB[i])){
map.put(ListB[i], n+i);
}
uf.union(map.get(ListA[i]), map.get(ListB[i]));
}
int globalmax = 0;
int maxindex = 0;
for(int i = 0; i < ListA.length; i++){
int index = uf.find(map.get(ListA[i]));
int size = uf.getSize(index);
if(size > globalmax) {
globalmax = size;
maxindex = index;
}
}
HashSet<String> set = new HashSet<String>();
for(int i = 0; i < ListA.length; i++) {
int root_a = uf.find(map.get(ListA[i]));
int root_b = uf.find(map.get(ListB[i]));
if(root_a == maxindex && !set.contains(ListA[i])){
result.add(ListA[i]);
set.add(ListA[i]);
}
if(root_b == maxindex && !set.contains(ListB[i])){
result.add(ListB[i]);
set.add(ListB[i]);
}
}
return result;
}
}