64,172
社区成员




面试题17.07.婴儿名字
解题思路:
1.并查集就是通过某些关系把原本散乱的点放入同一个集合中,一个集合只有一个相同的父节点。这么看的话,新生婴儿的名字有的是可以放入同一个集合中的,因此这题我们使用并查集来解决。
2.我们将名字映射到一个数字中放在一个unorder_map,将名字对应的婴儿数量放入另一个u_m中。因为名字映射到数字中,我们可以用一个整型数组来代表并查集,数组元素放着该节点的父节点的ID
3.当我们进行完并查集的init,find, merge操作后统计有多少个连通分量,连通分量的总和是多少(不断累加),连通分量最小的字典序是谁(不断修改为集合中的最小字典序)
class Solution {
public:
int fa[100010], groupSum[100010];
string groupName[100010];
unordered_map<string, int> name2Fre; //这个名字的数量
unordered_map<string, int> name2Id; //这个名字映射的Id
void init(int n) {
for(int i = 1; i <= n; ++i) {
fa[i] = i;
}
}
int find(int x) {
return (x == fa[x]) ? x : (fa[x] = find(fa[x]));
}
void merge(int i, int j) {
int x = find(i), y = find(j);
if(x == y) return;
else {
fa[x] = y;
}
}
string int2string(int i) {
if(!i) return "0";
string str = to_string(i);
return str;
}
vector<string> trulyMostPopular(vector<string>& names, vector<string>& synonyms) {
int idFrom0 = 0;
for(int i = 0; i < names.size(); ++i) {
int fre = 0, flag = 0;
string name = "";
for(int j = 0; j < names[i].size(); ++j) {
if(names[i][j] == '(') {
flag = 1;
//continue;
}
else if(flag == 1 && names[i][j] != ')') {
fre *= 10;
fre += names[i][j] - '0';
}
else if(flag == 0){
name += names[i][j];
}
}
name2Fre[name] = fre;
name2Id[name] = ++idFrom0;
}
init(100010 - 1);
for(int i = 0; i < synonyms.size(); ++i) {
string name1, name2;
int flag = 0;
for(int j = 0; j < synonyms[i].size(); ++j) {
if(synonyms[i][j] == ',') flag = 1;
else if(flag && synonyms[i][j] != ')') name2 += synonyms[i][j];
else if(!flag && synonyms[i][j] != '(') name1 +=synonyms[i][j];
}
if(name2Id[name1] == 0) {
name2Fre[name1] = 0;
name2Id[name1] = ++idFrom0;
}
if(name2Id[name2] == 0) {
name2Fre[name2] = 0;
name2Id[name2] = ++idFrom0;
}
merge(name2Id[name1], name2Id[name2]);
}
for(auto iter = name2Fre.begin(); iter != name2Fre.end(); ++iter) {
int id = name2Id[iter -> first]; //名字
int faId = find(id); //父节点编号
if(groupName[faId] == "" || iter -> first < groupName[faId]) { //只有一个父节点,所以其他节点不会被更新
groupName[faId] = iter -> first;
}
groupSum[faId] += name2Fre[iter -> first]; //数量
}
vector<string> ret;
for(int i = 1; i <= idFrom0; ++i) {
if(groupName[i] != "")
ret.push_back(groupName[i] + "(" + int2string(groupSum[i]) + ")");
}
return ret;
}
};