Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Move from brute-force thinking to an efficient approach using array strategy.
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 <= 1001 <= cpdomain[i].length <= 100cpdomain[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.Problem summary: 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. For example, "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.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array · Hash Map
["9001 discuss.leetcode.com"]
["900 google.mail.com", "50 yahoo.com", "1 intel.mail.com", "5 wiki.org"]
Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #811: Subdomain Visit Count
class Solution {
public List<String> subdomainVisits(String[] cpdomains) {
Map<String, Integer> cnt = new HashMap<>();
for (String s : cpdomains) {
int i = s.indexOf(" ");
int v = Integer.parseInt(s.substring(0, i));
for (; i < s.length(); ++i) {
if (s.charAt(i) == ' ' || s.charAt(i) == '.') {
String t = s.substring(i + 1);
cnt.put(t, cnt.getOrDefault(t, 0) + v);
}
}
}
List<String> ans = new ArrayList<>();
for (var e : cnt.entrySet()) {
ans.add(e.getValue() + " " + e.getKey());
}
return ans;
}
}
// Accepted solution for LeetCode #811: Subdomain Visit Count
func subdomainVisits(cpdomains []string) []string {
cnt := map[string]int{}
for _, s := range cpdomains {
i := strings.IndexByte(s, ' ')
v, _ := strconv.Atoi(s[:i])
for ; i < len(s); i++ {
if s[i] == ' ' || s[i] == '.' {
cnt[s[i+1:]] += v
}
}
}
ans := make([]string, 0, len(cnt))
for s, v := range cnt {
ans = append(ans, strconv.Itoa(v)+" "+s)
}
return ans
}
# Accepted solution for LeetCode #811: Subdomain Visit Count
class Solution:
def subdomainVisits(self, cpdomains: List[str]) -> List[str]:
cnt = Counter()
for s in cpdomains:
v = int(s[: s.index(' ')])
for i, c in enumerate(s):
if c in ' .':
cnt[s[i + 1 :]] += v
return [f'{v} {s}' for s, v in cnt.items()]
// Accepted solution for LeetCode #811: Subdomain Visit Count
struct Solution;
use std::collections::HashMap;
impl Solution {
fn subdomain_visits(cpdomains: Vec<String>) -> Vec<String> {
let mut res: Vec<String> = vec![];
let mut hm: HashMap<String, usize> = HashMap::new();
for s in cpdomains {
let (domains, count) = Self::parse(s);
for domain in domains {
let e = hm.entry(domain).or_default();
*e += count;
}
}
for (domain, count) in hm {
res.push(format!("{} {}", count, domain));
}
res
}
fn parse(s: String) -> (Vec<String>, usize) {
let mut domains: Vec<String> = vec![];
let mut iter = s.split_whitespace();
let count: usize = iter.next().unwrap().parse::<usize>().unwrap();
let domain: String = iter.next().unwrap().parse::<String>().unwrap();
for (i, c) in domain.chars().enumerate() {
if c == '.' {
let subdomain = &domain[i + 1..];
domains.push(subdomain.to_string());
}
}
domains.push(domain);
(domains, count)
}
}
#[test]
fn test() {
let input: Vec<String> = vec_string!["9001 discuss.leetcode.com"];
let mut answer: Vec<String> =
vec_string!["9001 discuss.leetcode.com", "9001 leetcode.com", "9001 com"];
let mut output = Solution::subdomain_visits(input);
answer.sort();
output.sort();
assert_eq!(answer, output);
let input: Vec<String> = vec_string![
"900 google.mail.com",
"50 yahoo.com",
"1 intel.mail.com",
"5 wiki.org"
];
let mut answer: Vec<String> = vec_string![
"901 mail.com",
"50 yahoo.com",
"900 google.mail.com",
"5 wiki.org",
"5 org",
"1 intel.mail.com",
"951 com"
];
let mut output = Solution::subdomain_visits(input);
answer.sort();
output.sort();
assert_eq!(answer, output);
}
// Accepted solution for LeetCode #811: Subdomain Visit Count
// Auto-generated TypeScript example from java.
function exampleSolution(): void {
}
// Reference (java):
// // Accepted solution for LeetCode #811: Subdomain Visit Count
// class Solution {
// public List<String> subdomainVisits(String[] cpdomains) {
// Map<String, Integer> cnt = new HashMap<>();
// for (String s : cpdomains) {
// int i = s.indexOf(" ");
// int v = Integer.parseInt(s.substring(0, i));
// for (; i < s.length(); ++i) {
// if (s.charAt(i) == ' ' || s.charAt(i) == '.') {
// String t = s.substring(i + 1);
// cnt.put(t, cnt.getOrDefault(t, 0) + v);
// }
// }
// }
// List<String> ans = new ArrayList<>();
// for (var e : cnt.entrySet()) {
// ans.add(e.getValue() + " " + e.getKey());
// }
// return ans;
// }
// }
Use this to step through a reusable interview workflow for this problem.
Two nested loops check every pair or subarray. The outer loop fixes a starting point, the inner loop extends or searches. For n elements this gives up to n²/2 operations. No extra space, but the quadratic time is prohibitive for large inputs.
Most array problems have an O(n²) brute force (nested loops) and an O(n) optimal (single pass with clever state tracking). The key is identifying what information to maintain as you scan: a running max, a prefix sum, a hash map of seen values, or two pointers.
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Wrong move: Zero-count keys stay in map and break distinct/count constraints.
Usually fails on: Window/map size checks are consistently off by one.
Fix: Delete keys when count reaches zero.