【LeetCode】49. Anagrams (2 solutions)

Anagrams

Given an array of strings, return all groups of strings that are anagrams.

Note: All inputs will be in lower-case.

首先解释一下什么是anagrams:在不考虑顺序的情况下,包含相同字母的字符串组成anagrams

例如:

1、{"eat","ate","tea","coffee"}的anagrams是{"eat","ate","tea"}

2、{"tea","and","ate","eat","dan"}的anagrams是{"tea","ate","eat","and","dan"}

解法一:排序之后的string作为key

在具体实现过程中,构造了两张映射表dict和exist

dict用来对排序过的单词进行快速查找,值(value)为第一个该编码的单词下标。

exist用来记录该排序过的单词是否已存在anagrams中,

如果是,只需要将当前单词装入anagrams;

如果不是,首先要将存放在m中的代表该排序过的单词的第一个单词装入anagrams,再装入当前单词。

class Solution {
public:
    vector<string> anagrams(vector<string> &strs) {
        vector<string> ret;
        unordered_map<string, int> dict;
        unordered_map<string, bool> exist;
        
        for(int i = 0; i < strs.size(); i ++)
        {
            string temp = strs[i];
            sort(temp.begin(), temp.end());
            if(dict.find(temp) == dict.end())
                dict[temp] = i;
            else
            {//find anagrams
                if(exist[strs[dict[temp]]] == false)
                {
                    ret.push_back(strs[dict[temp]]);
                    exist[strs[dict[temp]]] = true;
                }
                ret.push_back(strs[i]);
                exist[strs[i]] = true;
            }
        }
        
        return ret;
    }
};

解法二:利用质因数分解

背景:任何一个正整数都可以分解为唯一的质因数乘积:n=2a3b5c7d

因此n可以用{a,b,c,d}来唯一表示。

对于这个题,我们对a~z每个单词的出现次数作为每个质因数的次幂,

将乘积进行唯一编码,就可以忽略字母顺序了。相同编码的单词组成anagrams。

因为共有小写字母26个,因此我们需要前26个质因数。

在具体实现过程中,我还构造了两张映射表m和exist

dict用来对编码进行快速查找,值(value)为第一个该编码的单词下标。

exist用来记录该编码是否已存在anagrams中,

如果是,只需要将当前单词装入anagrams;

如果不是,首先要将存放在dict中的代表该编码的第一个单词装入anagrams,再装入当前单词。

class Solution {
public:
    vector<string> anagrams(vector<string> &strs) {
        vector<string> ret;
        vector<long long int> code(strs.size(), 0);
        CalCode(strs, code);
        map<long long int, int> dict;
        map<string, bool> exist;
        
        for(int i = 0; i < strs.size(); i ++)
        {
            if(dict.find(code[i]) == dict.end())
                dict[code[i]] = i;
            else
            {
                if(exist[strs[dict[code[i]]]] == false)
                {
                    exist[strs[dict[code[i]]]] = true;
                    ret.push_back(strs[dict[code[i]]]);
                }
                exist[strs[i]] = true;
                ret.push_back(strs[i]);
            }
        }
        return ret;
    }
    void CalCode(vector<string> &strs, vector<long long int> &code)
    {
        for(int i = 0; i < strs.size(); i ++)
        {
            string cur = strs[i];
            vector<int> count(26, 0); //a~z count
            for(int j = 0; j < cur.size(); j ++)
            {
                count[cur[j]-'a'] ++;
            }
            double prime[26] = {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};
            long long result = 1;
            for(int j = 0; j < 26; j ++)
            {
               result *= (long long int)pow(prime[j], count[j]);
            }
            code[i] = result;
        }
    }
};

原文地址:https://www.cnblogs.com/ganganloveu/p/4161264.html