Easy草稿★★★★★O(n * m) 時間 · O(n * m) 空間
StringHash Table
Patterns#️⃣ 雜湊
尚未複習過

解法已隱藏 — 先讀題目敘述、自己想想看,再點上方按鈕揭曉。

929Unique Email AddressesArrays & HashingEasyArrays & Hashing

每個電子郵件地址由 local name 和 domain name 組成,以 @ 分隔。規則:local name 中的 . 被忽略,+ 及其後面的字元被忽略。回傳不同實際地址的數量。

Example:

Input: emails = [“test.email+alex@leetcode.com”,“test.e.mail+bob.cathy@leetcode.com”,“testemail+david@lee.tcode.com”] Output: 2

Intuition

TIP

核心思路:對每個 email 按規則處理 local name(去 .、截斷 + 後面),再用 Set 去重計數。

Approaches

1. String Processing + Manual Parse — O(n * m) / O(n * m)
  • Idea: 手動遍歷 local name 的每個字元,遇到 . 跳過,遇到 + 停止
  • Time: O(n * m) - n 為 email 數量,m 為平均長度
  • Space: O(n * m) - Set 儲存
class Solution {
    fun numUniqueEmails(emails: Array<String>): Int {
        val unique = HashSet<String>()
        for (email in emails) {
            val parts = email.split("@")
            val local = parts[0]
            val domain = parts[1]
            val sb = StringBuilder()
            for (c in local) {
                if (c == '.') continue
                if (c == '+') break
                sb.append(c)
            }
            unique.add("$sb@$domain")
        }
        return unique.size
    }
}
⭐ 2. Built-in Functions — O(n * m) / O(n * m)
  • Idea: 用 splitreplacesubstringBefore 等內建函式簡潔處理
  • Time: O(n * m)
  • Space: O(n * m)
class Solution {
    fun numUniqueEmails(emails: Array<String>): Int {
        val unique = HashSet<String>()
        for (email in emails) {
            val (local, domain) = email.split("@")
            val cleanLocal = local.substringBefore("+").replace(".", "")
            unique.add("$cleanLocal@$domain")
        }
        return unique.size
    }
}

🔑 Takeaways