Unique Email Addresses

Easy · Arrays & Hashing · Explanation and code example

Iteration

How it works

Instead of using built-in string functions, we can manually iterate through each character of the email. This gives us more control and can be slightly more efficient since we process each character exactly once.

Steps

  1. Initialize an empty set unique to store unique email addresses.
  2. For each email e:
    • Initialize an empty string local and set index i = 0.
    • While the current character is not @ or +:
      • If the character is not ., append it to local.
      • Increment i.
    • Skip characters until we reach @.
    • Extract domain as the substring after @.
    • Add the normalized email (local + domain) to unique.
  3. Return the size of unique.

Complexity

  • Time complexity: O(n * m)
  • Space complexity: O(n)

Where n is the number of strings in the array, and m is the average length of these strings.

Things to watch for

Applying Local Name Rules to the Domain

A common mistake is applying the period-removal and plus-sign rules to the entire email address instead of just the local name. The domain portion (after the @ symbol) must remain unchanged. Periods in domain names like gmail.com are meaningful and should never be removed.

Incorrect Handling of the Plus Sign

Some solutions incorrectly remove only the + character itself rather than everything from + to the @. The rule states that everything after the first + in the local name should be ignored, not just the plus character. For example, in test+spam@gmail.com, the entire +spam portion must be discarded.

Python code example

from typing import List

class Solution:
    def numUniqueEmails(self, emails: List[str]) -> int:
        unique = set()

        for e in emails:
            i, local = 0, ""
            while e[i] not in ["@", "+"]:
                if e[i] != ".":
                    local += e[i]
                i += 1

            while e[i] != "@":
                i += 1
            domain = e[i + 1:]
            unique.add((local, domain))
        return len(unique)

C++ code example

class Solution {
public:
    int numUniqueEmails(vector<string>& emails) {
        unordered_set<string> unique;

        for (string e : emails) {
            int i = 0;
            string local = "";
            while (i < e.length() && e[i] != '@' && e[i] != '+') {
                if (e[i] != '.') {
                    local += e[i];
                }
                i++;
            }

            while (i < e.length() && e[i] != '@') {
                i++;
            }
            string domain = e.substr(i + 1);
            unique.insert(local + "@" + domain);
        }
        return unique.size();
    }
};
Source and license

Adapted from NeetCode’s source · MIT license. Node types are supplied by LeetCode where needed.

Your recall check is in progress. Write your attempt before revealing the explanation.

Resume recall check

Browse all problem explanations