OA原题描述参考:

注意:具体抽到的题目可能会有细微变化。

给了一些itemAssociation, 如果一个item既在association A里面出现过,又在association B里面出现过,那么就把A和B合并成一个association。求全部合并后最大的association。

如果两个association一样大,返回lexicographic order的第一个。

input:String[][] itemAssociation

return: String[]. visit 1point3acres.com for more.

example:

input:

[itemA, itemB]

[itemB, itemC]-google 1point3acres

[itemD, itemE]

合并之后:

[itemA, itemB, itemC].,

[itemD, itemE].

第一个有三个item最多,于是返回[itemA, itemB, itemC]

解题思路参考:

类似路径问题其实DFS,BFS和UnionFind都可以解决。这个因为是求最大的集合,用unionfind复杂度最好。坑:unionfind的模板是int数组,所以要把item放到一个hashmap里面产生唯一下标。根据下标做集合合并操作。合并时候注意size的计算是两个老大直接计算。输出结果需要费点劲。

参考答案:

package com.amazon;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by Tian on 2017/8/9.
 */
public class ItemAssociation {
    public static void main(String[] args) {
        String[][] items = {{"itemA", "itemB"}, {"itemB", "itemC"},
                {"itemD", "itemE"}, {"itemE", "itemF"}, {"itemG", "itemD"}};

        ItemAssociation ia = new ItemAssociation();
        String[] res = ia.count(items);
    }

    public String[] count(String[][] items) {
        int n = items.length;

        int index = 0;
        Map<String, Integer> hash = new HashMap<String, Integer>();
        for (int i = 0; i < n; i++) {
            if (!hash.containsKey(items[i][0])) hash.put(items[i][0], index++);
            if (!hash.containsKey(items[i][1])) hash.put(items[i][1], index++);
        }

        UnionFind un = new UnionFind(hash.size());

        for (int i = 0; i < n; i++) {
            un.union(hash.get(items[i][0]), hash.get(items[i][1]));
        }

        int maxIndex = un.findMaxSize();
        System.out.println(maxIndex);
        for (Map.Entry<String, Integer> entry : hash.entrySet()) {
            String key = entry.getKey();
            Integer ind = entry.getValue();
//            System.out.println(key + un.find(ind));
            if (un.find(ind) == maxIndex) {
                System.out.println(key);
            }
        }
        return null;
    }

    class UnionFind {
        int[] father = null;
        int[] size = null;
        UnionFind(int n) {
            father = new int[n];
            size = new int[n];
            for (int i = 0; i < n; i++) {
                father[i] = i; //father is itself
                size[i] = 1;
            }
        }

        void union(int a, int b) {
            int root_a = find(a);
            int root_b = find(b);
            if (root_a != root_b) {
                father[root_b] = root_a; //father merge
                size[root_a] += size[root_b];
            }
        }

        int find(int x) {
            if (father[x] == x) {
                return x;
            }

            return father[x] = find(father[x]);
        }

        int findMaxSize() {
            int max = 0;
            int index = 0;
            for (int i = 0; i < size.length; i++) {
//                System.out.println("father["+i+"]"+father[i]+" size[" +i +"]"+ size[i]);
                if (size[i] > max) {
                    max = size[i];
                    index = i;
                }
            }
            return index;
         }
    }
}

results matching ""

    No results matching ""