1. 程式人生 > >[LeetCode] Subdomain Visit Count 子域名訪問量統計

[LeetCode] 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.

這道題讓我們統計子域名的訪問量,所謂的子域名,就是一個完整的域名以點斷開的,每個斷開的地方到末尾之間的子字串就是一個子域名,現在給了我們很多完整域名的訪問量,讓我們統計所有子域名的訪問量,題目中給的例子很好的說明了問題。那麼這種統計字串出現個數的問題,我們應該不難想到需要用一個HashMap來建立字串和其出現次數的對映。那麼接下來要做的就是將每一個全域名提取出來,然後拆分成子域名。提取全域名操作不難,因為給的格式都是一樣的,前面是數字,中間一個空格,後面是全域名。我們只需要找到空格的位置,前面的部分轉為整型數cnt,後面的就是全域名了。取出全域名之後就要進行拆分成子域名了,我們可以進行遍歷,每當找到小數點的位置時,將後面的子字串的對映值增加cnt,以此類推直到拆完所有的子域名。注意之前的全域名的對映值別忘了也要加上cnt,最後的最後我們只要將HashMap中的對映對組成題目中要求返回的格式即可,參見程式碼如下:

解法一:

class Solution {
public:
    vector<string> subdomainVisits(vector<string>& cpdomains) {
        vector<string> res;
        unordered_map<string, int> subdomainCnt;
        for (string cpdomain : cpdomains) {
            int spaceIdx = cpdomain.find(" ");
            int cnt = stoi(cpdomain.substr(0, spaceIdx));
            string rem = cpdomain.substr(spaceIdx + 1);
            for (int i = 0; i < rem.size(); ++i) {
                if (rem[i] == '.') {
                    subdomainCnt[rem.substr(i + 1)] += cnt;
                }
            }
            subdomainCnt[rem] += cnt;
        }
        for (auto a : subdomainCnt) {
            res.push_back(to_string(a.second) + " " + a.first);
        }
        return res;
    }
};

下面這種解法和上面的基本相同,唯一改變的地方就是拆分子域名的時候,沒用使用遍歷的for迴圈,而是繼續使用了find函式來查詢下一個小數點的位置,參見程式碼如下:

解法二:

class Solution {
public:
    vector<string> subdomainVisits(vector<string>& cpdomains) {
        vector<string> res;
        unordered_map<string, int> subdomainCnt;
        for (string cpdomain : cpdomains) {
            int spaceIdx = cpdomain.find(" ");
            int cnt = stoi(cpdomain.substr(0, spaceIdx));
            while (spaceIdx != string::npos) {
                subdomainCnt[cpdomain.substr(spaceIdx + 1)] += cnt;
                spaceIdx = cpdomain.find('.', spaceIdx + 1);
            }
        }
        for (auto a : subdomainCnt) {
            res.push_back(to_string(a.second) + " " + a.first);
        }
        return res;
    }
};

參考資料: