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"]
]
Anagrams也就是同构异形体。特点是string有相同数量的char组成。
有两种方法,一直是把每个单词sort, 相同的anagrams肯定拥有同样的key. 时间复杂度O(klogk).
另一种方法,利用素数相乘,26个字母对应最小的26个素数,一个anagrams有唯一的key. 时间复杂度O(k).

1 素数相乘得到key。 (素数可以google素数表。)

public class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        int[] primes = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101};
        
        List<List<String>> res = new ArrayList<List<String>>();
        HashMap<Integer, Integer> map = new HashMap<>();   // key, position in array
        // 这里使用HashMap<Integer, Integer> 而不是 HashMap<String, List<String>> 可以避免最后从Map导出结果的时间。
        for(String str:strs){
            int key = 1;
            for(char c: str.toCharArray()){
                key *= primes[c-'a'];
            }
            List<String> t;
            if(map.containsKey(key)){
                t = res.get(map.get(key));
            } else {
                t = new ArrayList<String>();
                map.put(key, res.size());
                res.add(t);
            }
            t.add(str);
        }
        return res;
    }
}

2 sort

public class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        List<List<String>> res = new ArrayList<List<String>>();
        HashMap<String, Integer> map = new HashMap<>();   // key, position in array
        
        for(String str:strs){
            // 修改了hashmap和得到Key的方法, 其他都一样。
            char[] c = str.toCharArray();
            Arrays.sort(c);
            String key = String.valueOf(c);
            List<String> t;
            if(map.containsKey(key)){
                t = res.get(map.get(key));
            } else {
                t = new ArrayList<String>();
                map.put(key, res.size());
                res.add(t);
            }
            t.add(str);
        }
        return res;
    }
}

249 Group Shifted Strings

For example, given: ["abc", "bcd", "acef", "xyz", "az", "ba", "a", "z"], 
A solution is:
[
  ["abc","bcd","xyz"],
  ["az","ba"],
  ["acef"],
  ["a","z"]
]
拿"abc","bcd","xyz"这组举例子。 
"abc": 'b'-'a' = 1, 'c'-'a' = 2,  012
"bcd": 'c'-'b' = 1, 'd'-'c' = 2,  012
"xyz": 'y'-'x' = 1, 'z'-'x' = 2,  012
如果用数字做Key,上面都是12。但是会有解不了的地方。
还有个特殊情况就是"a", "aa", "aaa"不是一组。如果数字编码出来都是0.
如果用string编码,出现的就是0, 00, 000。就可以区分了。
public class Solution {
    public List<List<String>> groupStrings(String[] strings) {
        HashMap<String, List<String>> map = new HashMap<>();
        
        for(String s: strings){
            String key = getKey(s);
            List<String> value = map.get(key);
            if(value == null){
                value = new ArrayList<>();
                map.put(key, value);
            }
            value.add(s);
        }
        
        List<List<String>> res = new ArrayList<>();
        for(List<String> list: map.values()){
            Collections.sort(list); // dont forget to sort.
            res.add(list);
        }
        
        return res;
    }
    
    private String getKey(String s){
        int[] arr = new int[s.length()];
        for(int i = 1; i < s.length(); i++){
            arr[i] = s.charAt(i)-s.charAt(0) < 0? 
                     (s.charAt(i)-s.charAt(0) + 26): (s.charAt(i)-s.charAt(0));
        }
        return Arrays.toString(arr);
    }
}

288 Unique Word Abbreviation

a) it                      --> it    (no abbreviation)

     1
b) d|o|g                   --> d1g

              1    1  1
     1---5----0----5--8
c) i|nternationalizatio|n  --> i18n

              1
     1---5----0
d) l|ocalizatio|n          --> l10n
public class ValidWordAbbr {
    HashMap<String, String> map;
    
    public ValidWordAbbr(String[] dictionary) {
        map = new HashMap<>();
        for(String word : dictionary){
            String key = getKey(word);
            if(map.containsKey(key)){
                if(!map.get(key).equals(word)){
                    map.put(key, "");
                }
            } else {
                map.put(key, word);
            }
        }
        
    }
    
    public boolean isUnique(String word) {
        String key = getKey(word);
        return !map.containsKey(key) || map.get(key).equals(word);
    }
    
    public String getKey(String word){
        if(word.length() <= 2) return word;
        return word.charAt(0) + Integer.toString(word.length()-2) + word.charAt(word.length()-1);
    }
}

大米中的大米
12 声望5 粉丝

你的code是面向面试编程的,收集和整理leetcode discussion里个人认为的最优且最符合我个人思维逻辑的解法。