Maximum Association Set

Amazon sells books, every book has books which are strongly associated with it. Given ListA and ListB,indicates that ListA [i] is associated with ListB [i] which represents the book and associated books. Output the largest set associated with each other(output in any sort). You can assume that there is only one of the largest set.

Example

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]

Notice

  • The number of books does not exceed 5000.

思路:以书为node,建立一个<string,Integer> mapping, 注意size是2*n, 用不同的index代表不同的书,如果hashmap里面有了,就不用加了,是同一本书;union完之后,扫描一遍求出最大的size和最大的index,然后根据index来收集书名;注意去重,因为我是扫描了一遍书名,书名就有重复的,必须去重复;

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;
    }
}
发布了562 篇原创文章 · 获赞 13 · 访问量 17万+

猜你喜欢

转载自blog.csdn.net/u013325815/article/details/103922115
今日推荐