> ## Documentation Index
> Fetch the complete documentation index at: https://leetcode-py.wisl.dev/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> leetcode-py is a Python LeetCode practice environment generator with one CLI: lcpy. It is not a service or platform.
> Each problem is a directory under leetcode/ with README.md, solution.py, test_solution.py, helpers.py, and playground.ipynb. lcpy gen creates them from JSON templates bundled with the package.
> Examples are backed by tests; copy them verbatim.

# Unique Email Addresses Python Solution

> Tested Python solution for LeetCode 929 with 14 pytest cases. Generate a practice environment with lcpy.

LeetCode 929, [Easy](/catalog/easy). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/unique-email-addresses/description/).

Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 929   # by problem number
lcpy gen -s unique_email_addresses   # by problem name
```

## Problem

\<p>Every valid email consists of a local name and a domain name, separated by the \<code>'@'\</code> sign. Besides lowercase letters, the email may contain one or more \<code>'.'\</code> or \<code>'+'\</code>.\</p>

\<ul>
\<li>For example, in \<code>"[alice@leetcode.com](mailto:alice@leetcode.com)"\</code>, \<code>"alice"\</code> is the \<strong>local name\</strong>, and \<code>"leetcode.com"\</code> is the \<strong>domain name\</strong>.\</li>
\</ul>

\<p>If you add periods \<code>'.'\</code> between some characters in the \<strong>local name\</strong> part of an email address, mail sent there will be forwarded to the same address without dots in the local name. Note that this rule \<strong>does not apply\</strong> to domain names.\</p>

\<ul>
\<li>For example, \<code>"[alice.z@leetcode.com](mailto:alice.z@leetcode.com)"\</code> and \<code>"[alicez@leetcode.com](mailto:alicez@leetcode.com)"\</code> forward to the same email address.\</li>
\</ul>

\<p>If you add a plus \<code>'+'\</code> in the \<strong>local name\</strong>, everything after the first plus sign will be \<strong>ignored\</strong>. This allows certain emails to be filtered. Note that this rule \<strong>does not apply\</strong> to domain names.\</p>

\<ul>
\<li>For example, \<code>"[m.y+name@email.com](mailto:m.y+name@email.com)"\</code> will be forwarded to \<code>"[my@email.com](mailto:my@email.com)"\</code>.\</li>
\</ul>

\<p>It is possible to use both of these rules at the same time.\</p>

\<p>Given an array of strings \<code>emails\</code> where we send one email to each \<code>emails\[i]\</code>, return \<em>the number of different addresses that actually receive mails\</em>.\</p>

### Examples

```
Input: emails = ["test.email+alex@leetcode.com","test.e.mail+bob.cathy@leetcode.com","testemail+david@lee.tcode.com"]
Output: 2
Explanation: "testemail@leetcode.com" and "testemail@lee.tcode.com" actually receive mails.
```

```
Input: emails = ["a@leetcode.com","b@leetcode.com","c@leetcode.com"]
Output: 3
Explanation: All three addresses actually receive mails.
```

### Constraints

* 1 \<= emails.length \<= 100
* 1 \<= emails\[i].length \<= 100
* emails\[i] consist of lowercase English letters, '+', '.' and '@'.
* Each emails\[i] contains exactly one '@' character.
* All local and domain names are non-empty.
* Local names do not start with a '+' character.
* Domain names end with the ".com" suffix.
* Domain names must contain at least one character before ".com" suffix.

## Solution

Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/unique_email_addresses/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/unique_email_addresses/test_solution.py):

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
    # Time: O(n * m) where n = len(emails), m = avg email length
    # Space: O(n * m)
    def num_unique_emails(self, emails: list[str]) -> int:
        seen: set[str] = set()
        for email in emails:
            local, domain = email.split("@")
            local = local.split("+")[0].replace(".", "")
            seen.add(f"{local}@{domain}")
        return len(seen)
```

## Complexity

| Time | Space |
| - | - |
| O(n \* m) where n = len(emails), m = avg email length | O(n \* m) |

## Tags

[NeetCode All](/catalog/neetcode).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.