题目
929.
独特的电子邮件地址
每个 有效电子邮件地址 都由一个
本地名 和一个 域名 组成,以
'@'
符号分隔。除小写字母之外,电子邮件地址还可以含有一个或多个
'.'
或 '+'
。
- 例如,在
alice@leetcode.com
中, alice
是
本地名 ,而 leetcode.com
是
域名 。
如果在电子邮件地址的本地名部分中的某些字符之间添加句点('.'
),则发往那里的邮件将会转发到本地名中没有点的同一地址。请注意,此规则
不适用于域名 。
- 例如,
"alice.z@leetcode.com”
和
“alicez@leetcode.com”
会转发到同一电子邮件地址。
如果在本地名中添加加号('+'
),则会忽略第一个加号后面的所有内容。这允许过滤某些电子邮件。同样,此规则
不适用于域名 。
- 例如
m.y+name@email.com
将转发到
my@email.com
。
可以同时使用这两个规则。
给你一个字符串数组 emails
,我们会向每个
emails[i]
发送一封电子邮件。返回实际收到邮件的不同地址数目。
示例 1:
输入:emails =
["test.email+alex@leetcode.com","test.e.mail+bob.cathy@leetcode.com","testemail+david@lee.tcode.com"]
输出:2
解释:实际收到邮件的是 "testemail@leetcode.com" 和
"testemail@lee.tcode.com"。
示例 2:
输入:emails =
["a@leetcode.com","b@leetcode.com","c@leetcode.com"]
输出:3
提示:
1 <= emails.length <= 100
1 <= emails[i].length <= 100
emails[i]
由小写英文字母、'+'
、'.'
和 '@'
组成
- 每个
emails[i]
都包含有且仅有一个 '@'
字符
- 所有本地名和域名都不为空
- 本地名不会以
'+'
字符作为开头
标签
数组, 哈希表, 字符串
题解
【独特的电子邮件地址】简单模拟
模拟
由题意得:有效的电子邮件地址可以用 @
隔开,并且字符串中
@
只有一个,据此可以划分出本地名和域名,而域名无需任何处理,本地名有两个规则,总结如下:
所以只需提取第一个 +
前面的所有内容,并去掉所有的
.
就能得到真实的本地名,与域名拼接就得到了实际电子邮件地址。
而不重复的统计邮件地址可以借助哈希表,不带 split 的语言可以使用有限状态机的方法实现(见
Java
和 C++
代码实现)。
1 2 3 4 5 6 7
| class Solution: def numUniqueEmails(self, emails: List[str]) -> int: def convert(email): name, domain = email.split('@') return name.split('+')[0].replace('.', ''), domain return len(set("@".join(convert(e)) for e in emails))
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| class Solution { public: int numUniqueEmails(vector<string>& emails) { int state = 0; unordered_set<string> s; for (string& e: emails) { stringstream ss1, ss2; state = 0; for (char c: e) { if (c == '+' && state == 0) state = 1; if (c == '@') state = 2; if (c == '.' && state == 0) continue; if (state == 0) ss1 << c; else if (state == 2) ss2 << c; } ss1 << ss2.str(); s.emplace(ss1.str()); } return s.size(); } };
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| class Solution { public int numUniqueEmails(String[] emails) { int state = 0; Set<String> s = new HashSet<>(); for (String e: emails) { StringBuilder sb1 = new StringBuilder(), sb2 = new StringBuilder(); state = 0; for (int i = 0, n = e.length(); i < n; ++i) { char c = e.charAt(i); if (c == '+' && state == 0) state = 1; if (c == '@') state = 2; if (c == '.' && state == 0) continue; if (state == 0) sb1.append(c); else if (state == 2) sb2.append(c); } sb1.append(sb2.toString()); s.add(sb1.toString()); } return s.size(); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| class Solution { public int numUniqueEmails(String[] emails) { Set<String> s = new HashSet<>(); for (String e: emails) { String[] name_domain = e.split("@"); int idx = name_domain[0].indexOf("+"); s.add(name_domain[0].substring(0, (idx == -1 ? name_domain[0].length() : idx)).replace(".", "") + "@" + name_domain[1]); } return s.size(); } }
|
- 时间复杂度: \(O(nm)\), \(n, m\)
分布表示电子邮件地址的数量和平均长度
- 空间复杂度: \(O(\max (enails))\),
与电子邮件地址长度成正比
最后
如果对你有帮助的话,请给我点个赞吧~
欢迎前往 我的博客
或 Algorithm -
Github 查看更多题解