【leetcode】【medium】49. Group Anagrams

230 篇文章 0 订阅

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.

题目链接:https://leetcode.com/problems/group-anagrams/

n为string数,k为单个string长度。

法一:对string排序

时间复杂度:nklogk

空间复杂度:nk

对字符串补偿的情况表现好。

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        unordered_map<string,int> record;
        vector<vector<string>> res;
        for(int i =0; i<strs.size();++i){
            string tmp = strs[i];
            sort(tmp.begin(),tmp.end());
            if(record.find(tmp)!=record.end()){
                res[record[tmp]].push_back(strs[i]);
            }else{
                record[tmp] = res.size();
                vector<string> subres = {strs[i]};
                res.push_back(subres);
            }
        }
        return res;
    }
};

法二:每个串转为字符出现次数统计串

此法相当于把sort改进为了计算字母出现次数,从klogk降到k,其他步骤和法一一样。

但貌似实际运行结果反而变差了??难道是我打开方式不对???

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        unordered_map<string,int> record;
        vector<vector<string>> res;
        for(int i =0; i<strs.size();++i){
            string tmp = cal(strs[i]);
            if(record.find(tmp)!=record.end()){
                res[record[tmp]].push_back(strs[i]);
            }else{
                record[tmp] = res.size();
                vector<string> subres = {strs[i]};
                res.push_back(subres);
            }
        }
        return res;
    }
    string cal(string s){
        int res[26]={0};
        for(int i=0;i<s.length();++i){
            res[s[i]-'a']++;
        }
        string sres="";
        for(int i=0;i<26;++i){
            sres+=res[i];
            sres+='#';
        }
        return sres;
    }
};

法三:拆解成两个字符串的Anagram问题

从头开始,两层for循环,对没有分好类的字符串,比较二者的字符分布情况。

这里把sort的klogk复杂度改进为k,但在比较次数上上升了,最坏的情况是每个串是单独一类,复杂度就上升到了 (n^2)k

因此这种方法在串数量大、串变化复杂的情况不适用。

且实际运行证明这种思路确实超时不可行,无论是两层for循环的方法,还是只对类别对应代表串比较的方法。

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        unordered_map<string,int> record;
        vector<vector<string>> res;
        for(int i =0; i<strs.size();++i){
            bool isNew = true;
            for(int j=0;j<res.size();++j){
                if(isEqual(res[j][0],strs[i])){
                    isNew = false;
                    res[j].push_back(strs[i]);
                    break;
                }
            }
            if(isNew){
                vector<string> subres={strs[i]};
                res.push_back(subres);
            }
        }
        return res;
    }
    bool isEqual(string s1, string s2){
        unordered_map<char,int> record;
        for(int i=0;i<s1.length();++i){
            record[s1[i]]++;
        }
        for(int i=0;i<s2.length();++i){
            record[s2[i]]--;
            if(record[s2[i]]<0) return false;
        }
        return true;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值