题目来源于知识星球—英雄算法联盟,七月算法集训专题
前言
跟随英雄算法联盟博主—英雄哪里出来,每天完成相应的算法练习,一个月后,必定会有所成长!
今天还是看题解的一天!
一、面试题 17.07.婴儿名字(中等)
1.题目描述
2.解题思路
1. 将所有字符串映射到数字,使用unordered_map;
2. 每个字符串都是一个集合,有ID;
3. 根据每条关系,对ID进行合并;
4. 对每个集合进行统计、加和,选择字典序最小的记录。
3.代码演示(C++)
class Solution
{
#define maxn 100010
unordered_map <string, int> name2fre;
unordered_map <string, int> name2ID;
vector<string> ID2Name;
string groupname[maxn];
int groupfrq[maxn];
int f[maxn];
void init_set(int n)
{
for(int i = 1; i <= n; ++i)
{
f[i] = i;
}
}
int find_set(int n)
{
return (f[n]==n) ? n : (f[n] = find_set(f[n]));
}
int union_set(int a, int b)
{
int fa = find_set(a);
int fb = find_set(b);
if(fa == fb)
{
return 1;
}
f[fa] = fb;
return 0;
}
string num2String(int num)
{
if(!num)
{
return "0";
}
string ret;
while(num)
{
ret.push_back(num % 10 + '0');
num /= 10;
}
reverse(ret.begin(), ret.end());
return ret;
}
public:
vector<string> trulyMostPopular(vector<string>& names, vector<string>& synonyms)
{
int N = 0;
ID2Name.push_back("");
for(int i = 0; i < names.size(); ++i)
{
int flag = 0;
int fre = 0;
string name;
for(int j = 0; j < names[i].size(); ++j)
{
if(names[i][j] == '(')
{
flag = 1;
}
else if(flag && names[i][j] != ')')
{
fre = fre * 10 + names[i][j] - '0';
}
else if(flag == 0)
{
name += names[i][j];
}
}
name2fre[name] = fre;
name2ID[name] = ++N;
ID2Name.push_back(name);
}
init_set(maxn - 1);
for(int i = 0; i < synonyms.size(); ++i)
{
int flag = 0;
string first, second;
for(int j = 0; j < synonyms[i].size(); ++j)
{
if(synonyms[i][j] == '(' || synonyms[i][j] == ')')
{
}
else if(synonyms[i][j] == ',')
{
flag = 1;
}
else if(flag == 0)
{
first += synonyms[i][j];
}
else
{
second += synonyms[i][j];
}
}
if(name2ID[first] == 0)
{
name2fre[first] = 0;
name2ID[first] = ++N;
ID2Name.push_back(first);
}
if(name2ID[second] == 0)
{
name2fre[second] = 0;
name2ID[second] = ++N;
ID2Name.push_back(second);
}
union_set( name2ID[first], name2ID[second] );
}
for(auto it = name2fre.begin(); it != name2fre.end(); it++)
{
int ID = name2ID[it->first];
int setID = find_set(ID);
if (groupname[setID] == "" || it->first < groupname[setID])
{
groupname[setID] = it->first;
}
groupfrq[setID] += name2fre[it->first];
}
vector<string> ret;
for(int i = 1; i <= N; ++i)
{
if(groupfrq[i] == 0)
{
continue;
}
string s = groupname[i] + "(" + num2String(groupfrq[i]) + ")";
ret.push_back(s);
}
return ret;
}
};
4.题目链接
总结
每月的最后几天是比较难熬,多看看基础的算法思路,题目多看题解,记录一下。
每天跟随英雄哥学习相关的算法,一个月会收获很多,如果你想了解更多关于知识星球的内容,欢迎联系我!