LeetCode 049 Group Anagrams

本文介绍了三种解决Anagram归类问题的方法,包括使用特征向量、排序后的字符串以及质数哈希的方式,并对比了它们的运行效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:给出一组字符串,要求把由变化字母顺序而构成的单词(Anagram)归类。同一组中的单词要按字典序排列。

解法一:

把26个字母的出现次数存在vector中,作为key。把单词字符串组成的set作为value,存在一个map中。

代码:

    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        map<vector<int>, multiset<string>> f;
        for(int i = 0 ; i < strs.size() ; i++) {
            vector<int> feature(26, 0);
            for(int j = 0 ; j < strs[i].length() ; j++) {
                feature[strs[i][j] - 'a']++;
            }
            f[feature].insert(strs[i]);
        }

        vector<vector<string>> results;
        for(auto i = f.begin() ; i != f.end() ; ++i) {
            vector<string> tmp;
            for(auto j = i->second.begin() ; j != i->second.end() ; ++j) {
                tmp.push_back(*j);
            }
            results.push_back(tmp);
        }
        return results;
    }

提交以后运行时间为128 ms。

解法二:

上一种解法的vector,string参数传递比较占用时间。所以key使用排序后的string,value使用单词的index组成的vector,再使用hashmap存放。

代码:

    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        unordered_map<string, vector<int>> f;
        for(int i = 0 ; i < strs.size() ; i++) {
            string s = strs[i];
            sort(s.begin(), s.end());
            f[s].push_back(i);
        }

        vector<vector<string>> results;
        for(auto i = f.begin() ; i != f.end() ; ++i) {
            vector<string> tmp;
            for(auto j = i->second.begin() ; j != i->second.end() ; ++j) {
                tmp.push_back(strs[*j]);
            }
            sort(tmp.begin(), tmp.end());
            results.push_back(tmp);
        }
        return results;
    }

提交后运行时间为72ms。

解法三:

自己实现hash函数。设p_i为第i个质数,则前26个质数对应26个小写字母,将每个字母的出现次数作为对应质数的幂次,求乘积。这样Anagram求出来的hash值肯定是相同的(数论中质因数分解的唯一性)。

代码:

    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        unordered_map<int, vector<int>> f;
        int p[] = {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};
        for(int i = 0 ; i < strs.size() ; i++) {
            string s = strs[i];
            int tmp = 1;
            for(int j = 0 ; j < strs[i].length() ; j++)
                tmp *= p[strs[i][j] - 'a'];
            f[tmp].push_back(i);
        }

        vector<vector<string>> results;
        for(auto i = f.begin() ; i != f.end() ; ++i) {
            vector<string> tmp;
            for(auto j = i->second.begin() ; j != i->second.end() ; ++j) {
                tmp.push_back(strs[*j]);
            }
            sort(tmp.begin(), tmp.end());
            results.push_back(tmp);
        }
        return results;
    }

提交后运行时间仍然为72ms,估计这种方法如果自己实现hash容器会更快。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值