0%

『LeetCode』929 独特的电子邮件地址

题目

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 的语言可以使用有限状态机的方法实现(见 JavaC++ 代码实现)。

1
2
3
4
5
6
7
# Code language: Python
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
// Code language: C++
class Solution {
public:
int numUniqueEmails(vector<string>& emails) {
// 0 - 本地名中 `+` 前面部分
// 1 - 本地名中 `+` 后面部分
// 2 - 域名部分
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
// Code language: Java
class Solution {
public int numUniqueEmails(String[] emails) {
// 0 - 本地名中 `+` 前面部分
// 1 - 本地名中 `+` 后面部分
// 2 - 域名部分
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
// Code language: Java
class Solution {
public int numUniqueEmails(String[] emails) {
// split 实现
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 查看更多题解

--- ♥ end ♥ ---

欢迎关注我呀~