leetcode 811. 子域名访问计数

95 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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) {...}
}