持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第3天,点击查看活动详情
1. 题目与分析
网站域名 "discuss.leetcode.com" 由多个子域名组成。顶级域名为 "com" ,二级域名为 "leetcode.com" ,最低一级为 "discuss.leetcode.com" 。当访问域名 "discuss.leetcode.com" 时,同时也会隐式访问其父域名 "leetcode.com" 以及 "com" 。
计数配对域名 是遵循 "rep d1.d2.d3" 或 "rep d1.d2" 格式的一个域名表示,其中 rep 表示访问域名的次数,d1.d2.d3 为域名本身。
例如,"9001 discuss.leetcode.com" 就是一个 计数配对域名 ,表示 discuss.leetcode.com 被访问了 9001 次。 给你一个 计数配对域名 组成的数组 cpdomains ,解析得到输入中每个子域名对应的 计数配对域名 ,并以数组形式返回。可以按 任意顺序 返回答案。
输入:cpdomains = ["9001 discuss.leetcode.com"]
输出:["9001 leetcode.com","9001 discuss.leetcode.com","9001 com"]
解释:例子中仅包含一个网站域名:"discuss.leetcode.com"。 按照前文描述,子域名 "leetcode.com" 和 "com" 都会被访问,所以它们都被访问了 9001 次。
由题目可知,我们最终要输出的是一个对于所有涉及到的域名的计数的集合,因此我们会自然而然想到利用哈希表来实现。
2. 哈希表解法
确定了哈希表的实现形式,我们做的就是对输入字符串的解码,计数以及最终输出三个步骤。
public List<String> subdomainVisits(String[] cpdomains) {
Map<String, Integer> counts = decodeVisits(cpdomains);
List<String> ans = codeVisits(counts);
return ans;
}
接下来是解码部分,输入的cpdomain有两种形式,第一种是数字+“ ”+cpdomain,另一种是cpdomain,因此,我们可以通过 来将输入的字符串分为两部分,如果不存在 ,就直接以-1的索引分割字符串即可。
public Map<String, Integer> decodeVisits(String[] cpdomains) {
Map<String, Integer> counts = new HashMap<>();
for (String cpdomain : cpdomains) {
int space = cpdomain.indexOf(' ');
int count = Integer.parseInt(cpdomain.substring(0, space));
String domain = cpdomain.substring(space + 1);
counts.put(domain, counts.getOrDefault(domain, 0) + count);
for (int i = 0; i < domain.length(); i++) {
if (domain.charAt(i) == '.') {
String subdomain = domain.substring(i + 1);
counts.put(subdomain, counts.getOrDefault(subdomain, 0) + count);
}
}
}
return counts;
}
通过decodeVisits()方法能完成计数的过程,之后再按照要求编码输出即可。
public List<String> codeVisits(Map<String, Integer> counts) {
List<String> ans = new ArrayList<>();
for (Map.Entry<String, Integer> entry : counts.entrySet()) {
String subdomain = entry.getKey();
int count = entry.getValue();
ans.add(count + " " + subdomain);
}
return ans;
}
总体解题结构体如下所示,方法的具体实现前面已经给出,这里不再复制。
class Solution {
public List<String> subdomainVisits(String[] cpdomains) {...}
public List<String> codeVisits(Map<String, Integer> counts) {...}
public List<String> codeVisits(Map<String, Integer> counts) {...}
}