In the local part of an address (before the @), dots are ignored and
everything from the first + onward is ignored. The domain is used as-is.
How many distinct addresses are there?
numUniqueEmails([]string{ "test.email+alex@leetcode.com", "test.e.mail+bob.cathy@leetcode.com", "testemail+david@lee.tcode.com",}) // 2Normalise, then count
There is no algorithm here. The whole problem is applying two rules to the right half of the string and putting the results in a set.
test.email+alex@leetcode.com
test.email+alex@leetcode.com
Split at the @. Only the local part gets normalised — the domain is left exactly as it is.
func numUniqueEmails(emails []string) int { emailSet := make(map[string]struct{})
for _, email := range emails { parts := strings.Split(email, "@") local, domain := parts[0], parts[1]
local = strings.Split(local, "+")[0] local = strings.ReplaceAll(local, ".", "")
emailSet[local+"@"+domain] = struct{}{} }
return len(emailSet)}, and map[string]struct{} is
Go’s idiom for a set.
What Split is doing
strings.Split(email, "@") returns every field, and the code takes parts[1].
That assumes exactly one @, which the constraints guarantee. Without the
guarantee, "a@b@c.com" would silently use "b" as the domain and drop the
rest.
strings.Cut states the assumption and handles its absence:
local, domain, ok := strings.Cut(email, "@")if !ok { continue // or return an error — but now the case is visible}Cut splits on the first occurrence and reports whether it found one. It
also allocates nothing, where Split builds a slice. Since Go 1.18 it is the
right default for “split into two at a separator”.
Likewise strings.Split(local, "+")[0] builds every +-separated field to use
the first; local, _, _ = strings.Cut(local, "+") builds none.