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 = ; 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(), );
CalCode(strs, code);
map<long long int, int> dict;
map<string, bool> exist; for(int i = ; 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 = ; i < strs.size(); i ++)
{
string cur = strs[i];
vector<int> count(, ); //a~z count
for(int j = ; j < cur.size(); j ++)
{
count[cur[j]-'a'] ++;
}
double prime[] = {,,,,,,,,,,,,,,,,,,,,,,,,,};
long long result = ;
for(int j = ; j < ; j ++)
{
result *= (long long int)pow(prime[j], count[j]);
}
code[i] = result;
}
}
};

最新文章

  1. linux下的ssh工具之,本地上传到linux服务器and Linux服务器文件另存为本地。非sftp工具。
  2. IOS开发基础知识--碎片13
  3. BZOJ3542:DZY Loves March
  4. Postgresql 帐号密码修改方法
  5. ADO.NET常用对象的基础概念强化
  6. Winform开发框架之权限管理系统改进的经验总结(1)-TreeListLookupEdit控件的使用
  7. git 查看、创建、删除 本地,远程 分支
  8. 无责任Windows Azure SDK .NET开发入门篇一[Windows Azure开发前准备工作]
  9. linux下登陆用户的行为信息—w和who命令详解
  10. MongoDB实战指南(六):MongoDB复制集之复制集概述
  11. Mongodb中Sharding集群
  12. malloc和free的区别
  13. VlanTrunk
  14. MongoDB3.6 一键化自动部署方案
  15. day40 mycql 视图,触发器,存储过程,函数
  16. 关于XCode 的agvtool命令行
  17. ffff表单提交的那点事
  18. c++ queue 用法
  19. 瞎记录java (含this 的用法)
  20. 【[SHOI2015]脑洞治疗仪】

热门文章

  1. ffmpeg 2.3版本号, 关于ffplay音视频同步的分析
  2. Windows 7目录
  3. 定义和使用EL函数
  4. 【leetcode 桶排序】Maximum Gap
  5. DigCSDN介绍首页
  6. JavaScript 之 截取字符串函数
  7. mac 连接windows 共享内容
  8. iOS禁用系统休眠
  9. 微信小程序 - 更改radio和checkbox选中样式
  10. weblogic.servlet.proxy.HttpProxyServlet 进行代理设置