每封电子邮件都由一个本地名称和一个域名组成,以 @ 符号分隔。
例如,在 [email protected]
中, alice
是本地名称,而 leetcode.com
是域名。
除了小写字母,这些电子邮件还可能包含 '.'
或 '+'
。
如果在电子邮件地址的本地名称部分中的某些字符之间添加句点('.'
),则发往那里的邮件将会转发到本地名称中没有点的同一地址。例如,"[email protected]”
和 “[email protected]”
会转发到同一电子邮件地址。 (请注意,此规则不适用于域名。)
如果在本地名称中添加加号('+'
),则会忽略第一个加号后面的所有内容。这允许过滤某些电子邮件,例如 [email protected]
将转发到 [email protected]
。 (同样,此规则不适用于域名。)
可以同时使用这两个规则。
给定电子邮件列表 emails
,我们会向列表中的每个地址发送一封电子邮件。实际收到邮件的不同地址有多少?
示例:
输入:["[email protected]","[email protected]","[email protected]"] 输出:2 解释:实际收到邮件的是 "[email protected]" 和 "[email protected]"。
提示:
1 <= emails[i].length <= 100
1 <= emails.length <= 100
- 每封
emails[i]
都包含有且仅有一个'@'
字符。
自己的思路:
1、利用正则将email中的'.'替换掉
2、将+前和@之后的字符拼接成新的email
3、将新的email添加到set中,计算set大小
- 方案一(利用正则实现效率最低)
1 class Solution { 2 public int numUniqueEmails(String[] emails) { 3 Set<String> set = new HashSet<>(); 4 for (String email : emails) { 5 String localNamesWithoutPoint = email.split("@")[0].replaceAll("[.]", ""); 6 String result = localNamesWithoutPoint.split("\\+")[0] + "@" + email.split("@")[1]; 7 set.add(result); 8 } 9 return set.size(); 10 } 11 }
- 方案二(利用标准库中关于字符串的查找替换等方法实现)
1 class Solution { 2 public int numUniqueEmails(String[] emails) { 3 Set<String> emails_set = new HashSet<>(); 4 for(String email : emails) { 5 int start = email.indexOf('+'); 6 int end = email.indexOf('@'); 7 String localName = email.substring(0, start); 8 localName = localName.replace(".", ""); 9 String domainName = email.substring(end, email.length()); 10 emails_set.add(localName + domainName); 11 } 12 return emails_set.size(); 13 } 14 }
- 方案三(别人的13ms,利用空间复杂度换时间复杂度)
1 class Solution { 2 public int numUniqueEmails(String[] emails) { 3 if (emails == null) return 0; 4 HashSet<String> unique = new HashSet<String>(); 5 for (String email : emails) { 6 unique.add(realEmail(email)); 7 } 8 return unique.size(); 9 } 10 11 public String realEmail(String email) { 12 char[] impl = email.toCharArray(); 13 boolean metAt = false; 14 boolean metPlus = false; 15 int cur = 0, dst = 0; 16 while (cur < impl.length) { 17 if (metAt) { 18 impl[dst++] = impl[cur++]; 19 } else { 20 switch (impl[cur]) { 21 case '.': 22 cur++; 23 break; 24 case '+': 25 metPlus = true; 26 cur++; 27 break; 28 case '@': 29 metAt = true; 30 impl[dst++] = impl[cur++]; 31 break; 32 default: 33 if (metPlus) { 34 cur++; 35 } else { 36 impl[dst++] = impl[cur++]; 37 } 38 } 39 } 40 } 41 return new String(impl, 0, dst); 42 } 43 }