题目描述
每个 有效电子邮件地址 都由一个 本地名 和一个 域名 组成,以 '@'
符号分隔。除小写字母之外,电子邮件地址还可以含有一个或多个 '.'
或 '+'
。
- 例如,在
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]
都包含有且仅有一个 '@'
字符
- 所有本地名和域名都不为空
- 本地名不会以
'+'
字符作为开头
- 域名以
".com"
后缀结尾。
- 域名在
".com"
后缀前至少包含一个字符
解法
方法一:哈希表
利用哈希表存放转换后的电子邮件,最后返回哈希表的 size 即可。
| class Solution:
def numUniqueEmails(self, emails: List[str]) -> int:
s = set()
for email in emails:
local, domain = email.split('@')
local = local.replace('.', '')
if (i := local.find('+')) != -1:
local = local[:i]
s.add(local + '@' + domain)
return len(s)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | class Solution {
public int numUniqueEmails(String[] emails) {
Set<String> s = new HashSet<>();
for (String email : emails) {
String[] t = email.split("@");
String local = t[0].replace(".", "");
String domain = t[1];
int i = local.indexOf('+');
if (i != -1) {
local = local.substring(0, i);
}
s.add(local + "@" + domain);
}
return s.size();
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | class Solution {
public:
int numUniqueEmails(vector<string>& emails) {
unordered_set<string> s;
for (auto& email : emails) {
int i = email.find('@');
string local = email.substr(0, i);
string domain = email.substr(i + 1);
i = local.find('+', 0);
if (~i) local = local.substr(0, i);
while (~(i = local.find('.', 0)))
local.erase(local.begin() + i);
s.insert(local + "@" + domain);
}
return s.size();
}
};
|
| func numUniqueEmails(emails []string) int {
s := map[string]bool{}
for _, email := range emails {
i := strings.IndexByte(email, '@')
local := strings.SplitN(email[:i], "+", 2)[0]
local = strings.ReplaceAll(local, ".", "")
domain := email[i:]
s[local+domain] = true
}
return len(s)
}
|
| function numUniqueEmails(emails: string[]): number {
return new Set(
emails
.map(email => email.split('@'))
.map(([start, end]) => start.replace(/\+.*|\./g, '') + '@' + end),
).size;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 | use std::collections::HashSet;
impl Solution {
pub fn num_unique_emails(emails: Vec<String>) -> i32 {
let mut set = HashSet::new();
for email in emails.iter() {
let res: Vec<&str> = email.split('@').collect();
let mut s = String::new();
for &c in res[0].as_bytes().iter() {
if c == b'.' {
continue;
}
if c == b'+' {
break;
}
s.push(c as char);
}
s.push('@');
s.push_str(res[1]);
set.insert(s);
}
set.len() as i32
}
}
|
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 | const numUniqueEmails2 = function (emails) {
const emailFilter = function (str) {
let index = str.search(/@/);
let s = str.substring(0, index);
let s2 = str.substring(index + 1, str.length);
let res = '';
for (let i = 0; i < s.length; i++) {
if (s[i] === '+') break;
if (s[i] === '.') continue;
res = res + s[i];
}
return res + s2;
};
let arr = [];
for (let i = 0; i < emails.length; i++) {
let t = emailFilter(emails[i]);
if (arr.indexOf(t) === -1) {
arr.push(t);
}
}
return arr.length;
};
const numUniqueEmails = function (emails) {
let arr = emails.map(str => {
let index = str.search(/@/);
let s = str.substring(0, index);
let s2 = str.substring(index + 1, str.length);
let res = '';
for (let i = 0; i < s.length; i++) {
if (s[i] === '+') break;
if (s[i] === '.') continue;
res = res + s[i];
}
return res + s2;
});
let set = new Set(arr);
return set.size;
};
|