哈希表题目:独特的电子邮件地址

文章目录

  • 题目
    • 标题和出处
    • 难度
    • 题目描述
      • 要求
      • 示例
      • 数据范围
  • 解法
    • 思路和算法
    • 代码
    • 复杂度分析

题目

标题和出处

标题:独特的电子邮件地址

出处:929. 独特的电子邮件地址

难度

3 级

题目描述

要求

每个有效的电子邮件都由一个本地名称和一个域名组成,以 ‘@’ \texttt{`@'} ‘@’ 符号分隔。除了小写字母,电子邮件还可能包含一个或多个 ‘.’ \texttt{`.'} ‘.’ ‘+’ \texttt{`+'} ‘+’

如果在电子邮件地址的本地名称中的某些字符之间添加句点 ‘.’ \texttt{`.'} ‘.’,则发往那里的邮件将会转发到本地名称中没有点的同一地址。请注意,此规则不适用于域名

如果在本地名称中添加加号 ‘+’ \texttt{`+'} ‘+’,则会忽略第一个加号后面的所有内容。这允许过滤某些电子邮件,请注意,此规则不适用于域名

可以同时使用这两个规则。

给定字符串数组 emails \texttt{emails} emails,我们会向每个 emails[i] \texttt{emails[i]} emails[i] 发送一封电子邮件,返回实际收到邮件的不同地址数量。

示例

示例 1:

输入: ["[email protected]","[email protected]","[email protected]"] \texttt{["[email protected]","[email protected]","[email protected]"]} ["[email protected]","[email protected]","[email protected]"]
输出: 2 \texttt{2} 2
解释:实际收到邮件的是 "[email protected]" \texttt{"[email protected]"} "[email protected]" "[email protected]" \texttt{"[email protected]"} "[email protected]"

示例 2:

输入: emails   =   ["[email protected]","[email protected]","[email protected]"] \texttt{emails = ["[email protected]","[email protected]","[email protected]"]} emails = ["[email protected]","[email protected]","[email protected]"]
输出: 3 \texttt{3} 3

数据范围

  • 1 ≤ emails.length ≤ 100 \texttt{1} \le \texttt{emails.length} \le \texttt{100} 1emails.length100
  • 1 ≤ emails[i].length ≤ 100 \texttt{1} \le \texttt{emails[i].length} \le \texttt{100} 1emails[i].length100
  • emails[i] \texttt{emails[i]} emails[i] 由小写英语字母、 ‘+’ \texttt{`+'} ‘+’ ‘.’ \texttt{`.'} ‘.’ ‘@’ \texttt{`@'} ‘@’ 组成
  • 每个 emails[i] \texttt{emails[i]} emails[i] 都包含有且仅有一个 ‘@’ \texttt{`@'} ‘@’ 字符
  • 所有的本地名称和域名都是非空的
  • 本地域名的第一个字符不会是 ‘+’ \texttt{`+'} ‘+’

解法

思路和算法

为了计算实际收到邮件的不同地址数量,需要对每个电子邮件地址转换成实际收到邮件的地址,使用哈希集合存储实际收到邮件的地址。

由于实际收到邮件的地址和原地址的区别只可能发生在本地名称,因此只要对本地名称进行处理,得到实际收到邮件的地址的本地名称,然后拼接 ‘@’ \text{`@'} ‘@’ 符号和域名,即可得到实际收到邮件的完整地址。

由于哈希集合中的元素都不相同,因此在对每个电子邮件地址转换成实际收到邮件的地址并存入哈希集合之后,哈希集合中的元素个数即为实际收到邮件的不同地址数量。

代码

class Solution {
    public int numUniqueEmails(String[] emails) {
        Set<String> set = new HashSet<String>();
        for (String email : emails) {
            StringBuffer sb = new StringBuffer();
            int atIndex = email.indexOf('@');
            for (int i = 0; i < atIndex; i++) {
                char c = email.charAt(i);
                if (c == '+') {
                    break;
                }
                if (c == '.') {
                    continue;
                }
                sb.append(c);
            }
            sb.append(email.substring(atIndex));
            set.add(sb.toString());
        }
        return set.size();
    }
}

复杂度分析

  • 时间复杂度: O ( ∑ l e ) O(\sum l_e) O(le),即数组 emails \textit{emails} emails 中所有电子邮件地址的长度之和。需要 O ( ∑ l e ) O(\sum l_e) O(le) 的时间遍历所有电子邮件地址,对于每个电子邮件地址,生成实际收到邮件的地址和存入哈希表的时间为该电子邮件地址对应的实际收到邮件的地址的长度,其长度不会超过原始电子邮件地址的长度,因此总时间复杂度为 O ( ∑ l e ) O(\sum l_e) O(le)

  • 空间复杂度: O ( ∑ l e ) O(\sum l_e) O(le),即数组 emails \textit{emails} emails 中所有电子邮件地址的长度之和。需要使用哈希表存储每个电子邮件地址对应的实际收到邮件的地址,最坏情况下,每个电子邮件地址对应的实际收到邮件的地址都和原始电子地址邮件地址相同,且任意两个电子邮件地址都不同,此时哈希表的空间为所有电子邮件地址的长度之和。

你可能感兴趣的:(数据结构和算法,#,哈希表,哈希表)