LeetCode 刷题记录 49. Group Anagrams

题目:
Given an array of strings, group anagrams together.

Example:

Input: [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”],
Output:
[
[“ate”,“eat”,“tea”],
[“nat”,“tan”],
[“bat”]
]
Note:

All inputs will be in lowercase.
The order of your output does not matter.
解法1:通过排序法映射
将"ate",“eat”,“tea"排序后都为"aet”,然后将"aet"作为字典的键进行映射
c++:

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        vector<vector<string>> res;
        unordered_map<string, vector<string>> hash;
        for(string str : strs){
            string temp = str;
            sort(temp.begin(),temp.end());
            hash[temp].push_back(str);
        }
        for(auto a : hash){
            res.push_back(a.second);
        }
        return res;
    }
};

java:
String 不能直接排序,需要转换为字符数组str.toCharArray()
然后字符数组还需要转换为String key = String.valueOf(ca)
另外字典首先要查看键是否存在,不存在首先新建

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        Map<String, List<String>> hash = new HashMap<>();
        for(String str : strs){
            char[] ca = str.toCharArray();
            Arrays.sort(ca);
            String key = String.valueOf(ca);
            if(!hash.containsKey(key)) hash.put(key,new ArrayList<String>());
            hash.get(key).add(str);
        }
        
        return new ArrayList<List<String>>(hash.values());
    }
}

python:

  1. collections.defaultdict(list) 生成具有默认空列表的字典
  2. sorted(s) 进行排序,生成了s的一个副本
  3. sorted(s) 生成了一个列表,不能作为字典的键,因为列表是可变对象,因此需要转成元组不可变对象
class Solution(object):
    def groupAnagrams(self, strs):
        """
        :type strs: List[str]
        :rtype: List[List[str]]
        """
        ans = collections.defaultdict(list)
        for s in strs:
            ans[tuple(sorted(s))].append(s)
        return ans.values()

解法2;通过字符串中的字符的个数来映射
将26个字母的个数加上/分割形成唯一标识的字符串
c++:

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        vector<vector<string>> res;
        unordered_map<string, vector<string>> hash;
        for(string str : strs){
            vector<int> cnt(26,0);
            for(char c : str) cnt[c-'a']++;
            string key = "";
            for(int d : cnt) key += to_string(d) + "/";
            hash[key].push_back(str);
        }
        for(auto a : hash){
            res.push_back(a.second);
        }
        return res;
    }
};

java:

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        Map<String, List<String>> hash = new HashMap<>();
        int[] count = new int[26];
        for(String str : strs){
            Arrays.fill(count, 0);
            for(char c :str.toCharArray()) count[c-'a']++;
            StringBuilder sb = new StringBuilder("");
            for(int d : count){
                sb.append(d);
                sb.append("/");
            }
            String key = sb.toString();
            if(!hash.containsKey(key)) hash.put(key,new ArrayList<String>());
            hash.get(key).add(str);
        }
        
        return new ArrayList<List<String>>(hash.values());
    }
}

python:

class Solution(object):
    def groupAnagrams(self, strs):
        """
        :type strs: List[str]
        :rtype: List[List[str]]
        """
        ans = collections.defaultdict(list)
        for s in strs:
            count = [0] * 26
            for c in s:
                count[ord(c) - ord('a')] += 1
            ans[tuple(count)].append(s)
        return ans.values()

解法3:
用数字唯一标识
利用算术基本定理。

算术基本定理,又称为正整数的唯一分解定理,即:每个大于1的自然数,要么本身就是质数,要么可以写为2个以上的质数的积,而且这些质因子按大小排列之后,写法仅有一种方式。
用一个数组存储质数 prime = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103}。

然后每个字符串的字符减去 ’ a ’ ,然后取到 prime 中对应的质数。把它们累乘(参考49. Group Anagrams
c++:
有溢出,long long 也不可以,需用unsigned long long

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        int prime[26] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103 };
        vector<vector<string>> res;
        unordered_map<long long , vector<string>> hash;
        for(string str : strs){
            long long  key = 1;
            for(char c : str) key *= prime[c-'a'];
            
           
            hash[key].push_back(str);
        }
        for(auto a : hash){
            res.push_back(a.second);
        }
        return res;
    }
};

java:
Integer溢出后处理为负数

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        int[] prime = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103 };
        Map<Integer, List<String>> hash = new HashMap<>();
        
        for(String str : strs){
            int key = 1;
            for(char c :str.toCharArray()) key *= prime[c-'a'];
            System.out.println(key);
            
            if(!hash.containsKey(key)) hash.put(key,new ArrayList<String>());
            hash.get(key).add(str);
        }
        
        return new ArrayList<List<String>>(hash.values());
    }
}

python:

class Solution(object):
    def groupAnagrams(self, strs):
        """
        :type strs: List[str]
        :rtype: List[List[str]]
        """
        prime = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103 ]
        ans = collections.defaultdict(list)
        for s in strs:
            key = 1
            for c in s:
                key *= prime[ord(c) - ord('a')]
                #print key
            ans[key].append(s)
        return ans.values()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值