首先理解题目:
域名只有可能出现两种情况:(1)X.Y.Z 此时计算Z, Y.Z, X.Y.Z
(2)A.B 此时计算B, A.B
因此可以用从后到前的顺序,查找“.”或者“ ”,,把此位置之前的字符串保存下来即可。
class Solution {
public:
vector<string> subdomainVisits(vector<string>& cpdomains) {
unordered_map<string,int> result;
vector<string> ret;
for (int i = 0; i < cpdomains.size(); i++)
{
string nums = cpdomains[i].substr(0, cpdomains[i].find(' '));
int num;
stringstream ss; ss << nums; ss >> num;
for (int j = cpdomains[i].length(); j > 0; j--)
{
string tmp;
if ((cpdomains[i][j] == '.') || (cpdomains[i][j] == ' '))
{
tmp = cpdomains[i].substr(j + 1, cpdomains[i].size());
if (result.count(tmp)) result[tmp] = result[tmp] + num;
else result.insert(make_pair(tmp, num));
}
}
}
unordered_map<string, int>::iterator it;
for (it = result.begin(); it != result.end(); it++)
{
int num = it->second;
string tmp;
stringstream ss; ss << num; ss >> tmp;
tmp = tmp + ' ' + it->first;
ret.push_back(tmp);
}
return ret;
}
};
要点:
1.用string做Key的时候注意使用unordered_map。
2.string中查找位置用string.find(),复制子字符串使用string.substr(begin,end)
3.map中查找key是否存在时使用map.count(key),或者it=map.find(key),其中it是一个map的迭代器。
4.字符串和数字可以通过sstringstream相互转换。
5.如果map中已存在某个key的值,再用insert的时候,新的key值无法覆盖原来的key值(所以代码中判断了一下)。
只能插入pair类型,所以要用make_pair()
解答:
class Solution {
public:
vector<string> subdomainVisits(vector<string>& cpdomains) {
unordered_map<string, int> c;
for (auto cd : cpdomains) {
int i = cd.find(" ");
int n = stoi(cd.substr (0, i));
string s = cd.substr (i + 1, cd.size () - i - 1);
for (int i = 0; i < s.size(); ++i) if (s[i] == '.') c[s.substr(i + 1, s.size () - i)] += n;
c[s] += n;
}
vector<string> res;
for (auto k : c) res.push_back (to_string(k.second) + " " + k.first);
return res;
}
};
进行了几处优化:
1.stoi()把字符串转化为数字,to_string()把数字转化为字符串。
2.把域名提取出来,正向寻找“.”,可以比我的方法少遍历一些元素。
3.不需要用insert,直接赋值即可。
使用些方法可以是速度从前85%提升至1%。