子域名访问计数

Posted by zhouqian on Tuesday, July 26, 2022

力扣 811. 子域名访问计数

网站域名 “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 ,解析得到输入中每个子域名对应的 计数配对域名 ,并以数组形式返回。可以按 任意顺序 返回答案。


方案一:通过无序映射合并重复的子域名的访问次数。

func subdomainVisits(cpdomains []string) []string {
    // 通过无序映射合并重复的 key。key 为域名,val 为次数
    mp := make(map[string]int)
    for _, v := range cpdomains {
        // 拆分完整域名和访问次数
        info := strings.Split(v, " ")
        _cnt, cpd := info[0], info[1]
        cnt, _ := strconv.Atoi(_cnt)

        // 先将域名通过 . 分割
        domains := strings.Split(cpd, ".")
        // 然后遍历子域名,做合并操作(方便重新合成子域名)
        for i := 0; i < len(domains); i++ {
            mp[strings.Join(domains[i:], ".")] += cnt
        }
    }

    // 整理结果数组
    ans := make([]string, 0, len(mp))
    for k, v := range mp {
        ans = append(ans, fmt.Sprintf("%d %s", v, k))
    }
    return ans
} 
  • 时间复杂度:O(n),因为有个嵌套的循环,即遍历 cpdomains 然后执行子域名遍历操作,假设域名长度为常量,则时间复杂度为 O(n)。
  • 空间复杂度:O(n), 因为需要 n 的常数倍长度的无序映射保存中间结果,所以空间复杂度为 O(n)。