Subdomain Visit Count

Subdomain Visit Count is a string and counting question. It feels like real work an engineer does. You take messy text and turn it into clean totals. The interviewer wants to see if you can split a string carefully and add up counts with a hash map.

🎯 The Problem

You get count-and-domain strings and have to total the visits for every subdomain.

  • Each string looks like "9001 discuss.leetcode.com".
  • The number in front is how many times that full address was visited.
  • A subdomain is the address itself plus every shorter ending of it.
  • So discuss.leetcode.com also counts as a visit to leetcode.com and com.
  • You return the visit count for every subdomain.
Input: ["9001 discuss.leetcode.com"]
Output: ["9001 discuss.leetcode.com", "9001 leetcode.com", "9001 com"]
Explanation: 9001 visits to discuss.leetcode.com also means
9001 visits to leetcode.com and 9001 visits to com.

The order of the output does not matter. Each line is a count and a subdomain.

Here is how one input line spreads its count across the subdomains.

9001 discuss.leetcode.com

discuss.leetcode.com += 9001

leetcode.com += 9001

com += 9001

🐒 Approach 1: Collect Then Group (Brute Force)

The idea in one line: dump every subdomain into a long list first, then group and total them at the end.

The idea:

  • For each line, split off the number.
  • Break the address into its subdomains.
  • Store each subdomain with its count in a big list.

How it works:

  • After collecting, go back over the list.
  • Group the same subdomains together.
  • Add up their counts.

Why it is weak:

  • You hold a long list of repeated entries.
  • Then you sort or group them in a second pass.
  • That extra grouping pass is wasted work.

Here is the collect-then-group code:

subdomain_visit_count_collect.py
from collections import Counter
def subdomain_visits(cpdomains):
pieces = []
for item in cpdomains:
count, domain = item.split()
parts = domain.split(".")
for i in range(len(parts)):
pieces.append((int(count), ".".join(parts[i:])))
totals = Counter()
for count, domain in pieces:
totals[domain] += count
return [f"{count} {domain}" for domain, count in totals.items()]

⚑ Approach 2: One Pass With a Hash Map (Best)

The idea in one line: total each subdomain in a map the moment you build it, so no grouping pass is needed.

The idea:

  • A hash map stores a key and a value and looks the key up almost instantly.
  • Here the key is a subdomain and the value is its running total.

How it works:

  • For each line, split into the count and the address.
  • Turn the count text into a real number.
  • Build subdomains from the full address down to the last piece.
  • Chop the first piece off to get each shorter ending.
  • Add the count to each subdomain’s total in the map.
  • New subdomains start at zero, then take the count.
  • At the end, turn each map entry into a "count subdomain" line.

Why it is fast:

  • One pass adds all the counts.
  • No second grouping pass.
  • So the time is linear in the input length.

Here is the running map after the single input line.

read 9001 discuss.leetcode.com

map adds discuss.leetcode.com -> 9001

map adds leetcode.com -> 9001

map adds com -> 9001

output each key with its total

Steps to Solve

  1. Make an empty hash map from subdomain to total count.
  2. For each input line, split off the count and the full address.
  3. Turn the count text into a number.
  4. Build each subdomain by chopping pieces off the front of the address.
  5. Add the count to each subdomain’s total in the map.
  6. When done, turn each map entry into a "count subdomain" line and return them.

This Python version uses a dictionary from subdomain to total count.

subdomain_visit_count.py
def subdomain_visits(cpdomains):
counts = {} # subdomain -> total
for line in cpdomains:
count_str, domain = line.split(" ") # split number and address
count = int(count_str) # text "9001" -> number 9001
parts = domain.split(".") # ["discuss", "leetcode", "com"]
for i in range(len(parts)):
sub = ".".join(parts[i:]) # this subdomain ending
counts[sub] = counts.get(sub, 0) + count
result = []
for sub, total in counts.items():
result.append(str(total) + " " + sub)
return result
input_domains = ["9001 discuss.leetcode.com"]
for line in subdomain_visits(input_domains):
print(line)

The output of the above code will be:

9001 discuss.leetcode.com
9001 leetcode.com
9001 com

Let us walk through the Python version line by line, so the splitting is clear.

The line counts = {} makes an empty dictionary. It will map each subdomain to its running total.

The loop for line in cpdomains: reads each input line. Then count_str, domain = line.split(" ") splits the line at the space. The left side is the count as text. The right side is the full address.

The line count = int(count_str) turns the text "9001" into the number 9001. We need a real number to add it.

The line parts = domain.split(".") breaks the address at every dot. So discuss.leetcode.com becomes the list ["discuss", "leetcode", "com"].

The loop for i in range(len(parts)): walks each starting point. Then sub = ".".join(parts[i:]) joins the pieces from i to the end with dots. When i is 0 we get the full address. When i is 1 we get leetcode.com. When i is 2 we get com. So this builds every subdomain ending.

The line counts[sub] = counts.get(sub, 0) + count adds the count to that subdomain. The get(sub, 0) returns 0 if the subdomain is new. So new ones start fresh and old ones keep growing.

⏱️ Time and Space Complexity

Say there are n input lines and each address has up to a few pieces. The brute force collects everything then groups it in a second pass. The hash map adds counts right away in a single pass. Both touch each piece a fixed number of times, so the time is O(n) in the total length of the input. The map also needs O(n) space to hold the subdomains.

Approach Time Complexity Space Complexity
Brute force (collect then group) O(n) O(n)
One pass with hash map O(n) O(n)

Tip

The skill being tested is careful string handling. Split the count from the address first. Then build the subdomains from the right side. Get those two splits right and the counting is the easy part.

🧩 Key Takeaways

  • βœ… A visit to a full address counts as a visit to every shorter ending too.
  • βœ… Split each line into the count and the address first.
  • βœ… Build subdomains by chopping pieces off the front of the address.
  • βœ… A hash map adds up counts in one pass, with no grouping step at the end.
  • βœ… Turn the count text into a real number before adding it.

Check Your Knowledge

4 questions Show quiz Hide quiz

Test what you learned. Pick an answer for each question, then click Check.

  1. 1

    For the address discuss.leetcode.com, which subdomains get the visit count?

    Why: Every shorter ending counts too, so the full address plus leetcode.com plus com all get the count.

  2. 2

    Why is the hash map approach better than collecting everything first?

    Why: The map totals each subdomain as it is seen, so there is no second pass to group and sum.

  3. 3

    What is the first split you do on an input line like "9001 discuss.leetcode.com"?

    Why: First separate the count and the address at the space, then split the address on dots.

  4. 4

    What is the time complexity of the one-pass hash map solution?

    Why: Each piece of the input is processed a fixed number of times, so the work is linear in the input length.

πŸš€ What’s Next?