49. Group Anagrams

Given an array of strings, group anagrams together.
For example, given: ["eat", "tea", "tan", "ate", "nat", "bat"],
Return:
[
["ate", "eat","tea"],
["nat","tan"],
["bat"]
]
Note: All inputs will be in lower-case.

弱菜解法(Time Limit Exceeded):

这些anagrams的相同之处是,map到一个数组中的时候对应的位会相同。所以我扫描每个词,这个数组对应成一个数组模拟的map,作为HashMap的key。这有个问题,就是每次new的数组都是不一样的对象,不能用containsKey做O(1)查找,而需要用Iterator一个个的遍历key,然后用Arrays.equals来对比,徒增了O(n)的复杂度。目测复杂度是O(n2)。
贴一下:

    public List> groupAnagrams(String[] strs) {
        Map> hashMap = new HashMap<>();
        for (String s : strs) {
            boolean addedToExist = false ;
            int[] map = new int[26];
            for (int i = 0; i < s.length(); i++) {
                map[s.charAt(i) - 'a']++;
            }
            if (hashMap.isEmpty()) {
                hashMap.put(map, new ArrayList());
            }
            Iterator iter = hashMap.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry entry = (Map.Entry) iter.next();
                int[] key = (int[]) entry.getKey();
                if (Arrays.equals(key, map)) {
                    List list = hashMap.get(entry.getKey());
                    list.add(s);
                    addedToExist = true;
//                  hashMap.put(key, list);//这里是否不需要put,因为list是引用
                }
            }
            if (!addedToExist){
                List list = new ArrayList<>();
                list.add(s);
                hashMap.put(map , list);
            }

        }

        List> res = new ArrayList<>();
        Iterator iter = hashMap.entrySet().iterator();
        while (iter.hasNext()) {
            Map.Entry> entry = (Map.Entry>) iter.next();
            List list = entry.getValue();
            res.add(list);
        }
        return res;
    }

好的解法:

用string做

    public List> groupAnagrams(String[] strs) {
        if (strs == null || strs.length == 0 ) return new ArrayList<>();
        Map> map = new HashMap<>();
        for (String s : strs){
            char [] c = s.toCharArray();
            Arrays.sort(c);
            String key = String.copyValueOf(c);
            if (map.containsKey(key)){
                map.get(key).add(s);
            }else {
                List list = new ArrayList<>();
                list.add(s);
                map.put(key, list);
            }
        }
        return new ArrayList<>(map.values());
    }

这个解法用sort巧妙地用String来作为key了。但我又想,不同内存地址的String,containsKey能返回true吗。。查了一下,因为String的hashCode是按照字符的utf-16的编码值求和,所以hash相同;hashmap用hash作为key,containsKey就会返回true了。

还可以精简成:

            if (!map.containsKey(key)){
                map.put(key, new ArrayList());
            }
            map.get(key).add(s);

另外,把所有value加进ArrayList不需要Iterator,直接用 return new ArrayList<>(map.values());就行。


上周去了St. Petersburg,转眼间一周过去了,真的快。下面我想执行一个每天晚上学习三小时的计划。

ref:
http://blog.csdn.net/donlian/article/details/16892423

你可能感兴趣的:(49. Group Anagrams)