811. Subdomain Visit Count*

811. Subdomain Visit Count*

https://leetcode.com/problems/subdomain-visit-count/

题目描述

A website domain like “discuss.leetcode.com” consists of various subdomains. At the top level, we have “com”, at the next level, we have “leetcode.com”, and at the lowest level, “discuss.leetcode.com”. When we visit a domain like “discuss.leetcode.com”, we will also visit the parent domains “leetcode.com” and “com” implicitly.

Now, call a “count-paired domain” to be a count (representing the number of visits this domain received), followed by a space, followed by the address. An example of a count-paired domain might be “9001 discuss.leetcode.com”.

We are given a list cpdomains of count-paired domains. We would like a list of count-paired domains, (in the same format as the input, and in any order), that explicitly counts the number of visits to each subdomain.

Example 1:

Input: 
["9001 discuss.leetcode.com"]
Output: 
["9001 discuss.leetcode.com", "9001 leetcode.com", "9001 com"]
Explanation: 
We only have one website domain: "discuss.leetcode.com". As discussed above, the subdomain "leetcode.com" and "com" will also be visited. So they will all be visited 9001 times.

Example 2:

Input: 
["900 google.mail.com", "50 yahoo.com", "1 intel.mail.com", "5 wiki.org"]
Output: 
["901 mail.com","50 yahoo.com","900 google.mail.com","5 wiki.org","5 org","1 intel.mail.com","951 com"]
Explanation: 
We will visit "google.mail.com" 900 times, "yahoo.com" 50 times, "intel.mail.com" once and "wiki.org" 5 times. For the subdomains, we will visit "mail.com" 900 + 1 = 901 times, "com" 900 + 50 + 1 = 951 times, and "org" 5 times.

Notes:

  • The length of cpdomains will not exceed 100.
  • The length of each domain name will not exceed 100.
  • Each address will have either 1 or 2 "." characters.
  • The input count in any count-paired domain will not exceed 10000.
  • The answer output can be returned in any order.

C++ 实现 1

题目不难, 但实现时不小心弄出一个 bug, 导致排查了很久, 差点心态崩了. 先给出代码, 之后介绍写出的 bug.

使用 stringstream 来处理字符串, 获取 domain 以及 count. 通过字符串的 find 方法, 找到各个 ".", 以便求得 subdomain, 最后用哈希表统计各个域名的个数.

class Solution {
public:
    vector<string> subdomainVisits(vector<string>& cpdomains) {
        unordered_map<string, int> record;
        for (auto &s : cpdomains) {
            stringstream ss(s);
            int count = 0;
            string domain;
            ss >> count >> domain;
            record[domain] += count;
            int i = 0;
            while (true) {
                i = domain.find('.', i);
                if (i == std::string::npos) break;
                i ++;
                auto subdomain = domain.substr(i, domain.size() - i);
                record[subdomain] += count;
            }
        }
        vector<string> res;
        for (auto &p : record) {
            auto s = std::to_string(p.second) + " " + p.first;
            res.push_back(s);
        }
        return res;
    }
};

出现 bug 的地方在:

ss >> count >> domain;
record[domain] += count;

当时写错成:

ss >> count >> domain;
record[domain] = count;

报错的测试用例看着让我绝望:

在这里插入图片描述
输出结果总共有 162 个, 161 个是正确的结果, 只有一个错误的… 可以想见我当时的心情是多么的崩溃.
但人有的时候就是容易固执, 我特别想找出我错误的地方, 主要出于以下几种心情的混合:

  • 报错了, 心里不爽
  • 如果放过这个错误, 它就用于在那, 我要被它一直折磨;
  • 我觉得我应该可以找出这个 bug, 这在我的能力范围之内, 只是当前的测试用例不那么友好
  • 它就应该被我解决
  • 我觉得我代码中的核心部分应该是没有问题, 如果被其中的一个小错误致使我放弃这段代码, 不划算

后来的处理方法是, 首先分析结果, 使用 Python 对结果进行排序, 找到 OutputExpected 出现差异的字符串, 结果是:

## Output
1225 lmm.ca
654 yaw.lmm.ca

## Expected
1879 lmm.ca
654 yaw.lmm.ca

就这一个不同, 于是发现了问题所在, lmm.ca 的结果没有被累加. 但是原因是啥呢? 继续查 C++ 代码, 发现第二次访问 lmm.ca 时, 使用 record[domain] = count; 会将第一次的结果覆盖!

Finally, 心头的阴霾散去了. 不要问我值不值得, 我觉得只要能最终解决这个问题, 就算是有收益.

C++ 实现 2

两年前的代码.

class Solution {
private:
    vector<int> dotIndex(string &domain) {
        vector<int> res{-1}; // 用 -1 初始化, 非常机智
        for (int i = 0; i < domain.size(); ++i)
            if (domain[i] == '.')
                res.push_back(i);
        return res;
    }
public:
    vector<string> subdomainVisits(vector<string>& cpdomains) {
        unordered_map<string, int> record;
        for (auto &cp : cpdomains) {
            stringstream ss(cp);
            int count;
            string domain;
            ss >> count >> domain;
            vector<int> indes = dotIndex(domain);
            int len = domain.size();
            for (auto &idx : indes) {
                record[domain.substr(idx + 1, len - idx - 1)] += count;
            }
        }

        vector<string> res;
        for (auto &iter : record) {
            string ans = to_string(iter.second) + " " + iter.first;
            res.push_back(ans);
        }
        return res;
    }
};
发布了394 篇原创文章 · 获赞 8 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/Eric_1993/article/details/104761495