A website domain "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.
A count-paired domain is a domain that has one of the two formats "rep d1.d2.d3"
or "rep d1.d2"
where rep
is the number of visits to the domain and d1.d2.d3
is the domain itself.
"9001 discuss.leetcode.com"
is a count-paired domain that indicates that discuss.leetcode.com
was visited 9001
times.Given an array of count-paired domains cpdomains
, return an array of the count-paired domains of each subdomain in the input. You may return the answer in any order.
Example 1:
Input: cpdomains = ["9001 discuss.leetcode.com"] Output: ["9001 leetcode.com","9001 discuss.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: cpdomains = ["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.
Constraints:
1 <= cpdomain.length <= 100
1 <= cpdomain[i].length <= 100
cpdomain[i]
follows either the "repi d1i.d2i.d3i"
format or the "repi d1i.d2i"
format.repi
is an integer in the range [1, 104]
.d1i
, d2i
, and d3i
consist of lowercase English letters.This problem involves processing a list of count-paired domains and returning a list of all subdomains and their visit counts. The solution uses a hash map (dictionary in Python) to efficiently store and count subdomain visits.
Approach:
Initialization: A hash map (or dictionary) is created to store subdomains as keys and their visit counts as values.
Iterating through Count-Paired Domains: The code iterates through each cpdomain
string in the input list.
Parsing the Count and Domain: For each cpdomain
, the code splits it into the visit count (an integer) and the domain name.
Subdomain Generation and Counting: The code then iterates through the domain name, splitting it at each dot (.
) to generate all subdomains. For example, "discuss.leetcode.com" would generate "discuss.leetcode.com", "leetcode.com", and "com". Each generated subdomain is added to the hash map, and its count is incremented by the visit count obtained in step 3.
Result Formatting: Finally, the code iterates through the hash map and creates a list of strings in the format "count subdomain" and returns this list.
Time Complexity Analysis:
cpdomains
list, which has a length of n
.m
. In the worst case, the domain name could be a single, long subdomain. The number of subdomains generated is at most the length of the domain string.Therefore, the overall time complexity is O(n*m), where n
is the number of count-paired domains and m
is the maximum length of a domain name.
Space Complexity Analysis:
n
is the number of count-paired domains and m
is the maximum length of a domain name. However, in practice this space may be considerably less as many subdomains will share common suffixes.Code Examples (with explanations inline):
Python:
from collections import Counter
class Solution:
def subdomainVisits(self, cpdomains: List[str]) -> List[str]:
cnt = Counter() # Use Counter for efficient counting
for domain in cpdomains:
count, domain_str = domain.split() # Split into count and domain
count = int(count) # Convert count to integer
subdomains = domain_str.split('.') # Split domain into subdomains
for i in range(len(subdomains)):
subdomain = ".".join(subdomains[i:]) # Reconstruct subdomains
cnt[subdomain] += count # Increment count for each subdomain
result = [f"{count} {subdomain}" for subdomain, count in cnt.items()] # Format result
return result
Java:
import java.util.*;
class Solution {
public List<String> subdomainVisits(String[] cpdomains) {
Map<String, Integer> countMap = new HashMap<>(); //Use HashMap for efficient counting
for (String domain : cpdomains) {
String[] parts = domain.split("\\s+"); //Split into count and domain using regex for whitespace
int count = Integer.parseInt(parts[0]); //Convert count to integer
String[] subdomains = parts[1].split("\\."); // Split domain into subdomains using regex for dot
for (int i = 0; i < subdomains.length; i++) {
StringBuilder sb = new StringBuilder();
for (int j = i; j < subdomains.length; j++) {
sb.append(subdomains[j]);
if (j < subdomains.length -1) sb.append("."); // Add dot if not last subdomain
}
String subdomain = sb.toString();
countMap.put(subdomain, countMap.getOrDefault(subdomain, 0) + count); //Increment count
}
}
List<String> result = new ArrayList<>();
for (Map.Entry<String, Integer> entry : countMap.entrySet()) {
result.add(entry.getValue() + " " + entry.getKey()); // Format result
}
return result;
}
}
The other languages (C++, Go) would follow a very similar structure using their respective hash map implementations and string manipulation functions. The core logic remains the same across all languages.