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.

  • 题解

题解1 - 双重for循环(TLE)

题 Two Strings Are Anagrams 的升级版,容易想到的方法为使用双重for循环两两判断字符串数组是否互为变位字符串。但显然此法的时间复杂度较高。还需要 O(n)O(n) 的数组来记录字符串是否被加入到最终结果中。

1.c++ implement

class Solution{
public:
    vector<string> anagrams(vector<string> &strs){
        if(strs.size()<2){
            return strs;
        }
        
        vector<string> result;
        vector<bool> visited(strs.size(),false);
        for(int s1=0;s1!=strs.size();++s1){
            
            bool has_anagrams=false;
            for(int s2=s1+1;s2!=strs.size();++s2){
                if((!visited[s2] && isAnagrams(strs[s1],strs[s2]))){
                    result.push_back(strs[s2]);
                    visited[strs[s2]]=true;
                    has_anagrams=true;
                }
            }
            if(!visited[strs[s1]] && has_anagrams){
                result.push_back(strs[s1]);
            }
        }
   return result;
    }
private:
    bool isAnagrams(string &s,string &t){
        if(s.size()!=t.size()) return false;
        
        const int AlphaNum=26;
        int letterCount[AlphaNum]={0};
        
        for(int i=0;i!=s.size();++i){
            ++letterCount[s[i]-'a'];
            --letterCount[t[i]-'a'];
        }
        
        for(int i=0;i!=t.size();++i){
            if(letterCount[t[i]-'a']<0){
                return false;
            }
        }
        return true;
    }
};
  • 复杂度分析

私有方法isAnagrams最坏的时间复杂度为 O(2L)O(2L), 其中 LL 为字符串长度。双重for循环时间复杂度近似为 \frac {1}{2} O(n^2)​2​​1​​O(n​2​​), nn 为给定字符串数组数目。总的时间复杂度近似为 O(n^2 L)O(n​2​​L). 使用了Vector String "visited",空间复杂度可认为是 O(n)O(n).

  • 题解2

在题 Two Strings Are Anagrams 中曾介绍过使用排序和 hashmap 两种方法判断变位词。这里我们将这两种方法同时引入!只不过此时的 hashmap 的 key 为字符串,value 为该字符串在 vector 中出现的次数。两次遍历字符串数组,第一次遍历求得排序后的字符串数量,第二次遍历将排序后相同的字符串取出放入最终结果中。

1.python implement

class Solution:
    # @param strs: A list of strings
    # @return: A list of strings
    # @return: A list of strings
    def anagrams(self, strs):
        strDict={}
        result=[]
        for string in strs:
            if  "".join(sorted(string)) not in strDict.keys():
                strDict["".join(sorted(string))] = 1
            else: 
                strDict["".join(sorted(string))] += 1
        for string in strs:
            if strDict["".join(sorted(string))] >1:
                result.append(string)
        return result

2.C++ implement

#include <iostream>
#include<vector>
#include<string>
#include<map>
#include<algorithm>
using namespace std;
class Solution {
public:
   vector<vector<string>> anagrams(vector<string> &strs) {
        map<string, vector<string>> anagram;
        vector<vector<string>> result;
        for (int i = 0; i < strs.size(); i++) {
            string str = strs[i];
            sort(str.begin(), str.end());
            if (anagram.find(str)==anagram.end()) {
                std::vector<string> item;
                anagram[str]=item;
            }
            anagram[str].push_back(strs[i]);
        }
        map<string,vector<string>> ::iterator it;
        for(it=anagram.begin();it!=anagram.end();it++){
            result.push_back((*it).second);
        }

        return result;
    }
};
int main()
{
    Solution solve;
    vector<string> strs;
    vector<vector<string>> temp;
    strs={"eat", "tea", "tan", "ate", "nat", "bat"};
    temp=solve.anagrams(strs);
    cout<<"[";
    for(int i=0;i<temp.size();i++){
        cout<<"[";
        for(int j=0;j<temp[i].size();j++){
            cout<<"\""<<temp[i][j]<<"\""<<",";
        }
        cout<<"]";
        cout<<endl;
    }
    cout<<"]";

    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值