LeetCode.927-独特邮箱地址(Unique Email Addresses)

这是悦乐书的第356次更新,第383篇原创

01看题和准备

今天介绍的是LeetCode算法题中Easy级别的第218题(顺位题号是927)。每封电子邮件都包含本地名称和域名,以@符号分隔。

例如,在alice@leetcode.com中,alice是本地名称,leetcode.com是域名。

除了小写字母,这些电子邮件可能包含'.''+'

如果在电子邮件地址的本地名称部分中的某些字符之间添加句点('.'),则在那里发送的邮件将转发到本地名称中没有点的同一地址。例如,“alice.z@leetcode.com”“alicez@leetcode.com”转发到同一个电子邮件地址。(请注意,此规则不适用于域名。)

如果在本地名称中添加加号('+'),则会忽略第一个加号后面的所有内容。这允许过滤某些电子邮件,例如m.y+name@email.com将转发到my@email.com。(同样,此规则不适用于域名。)

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

给定电子邮件列表,我们会向列表中的每个地址发送一封电子邮件。有多少不同的地址实际接收邮件?例如:

输入:[“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”实际收到邮件

注意

  • 1 <= emails[i].length <= 100

  • 1 <= emails.length <= 100

  • 每封emails[i]都包含一个'@'字符。

  • 所有本地名称和域名都是非空的。

  • 本地名称不以“+”字符开头。

02 第一种解法

根据题目给的规则,对字符串分两段处理,在本地名称中,如果存在+号,就截取+号前的字符串,变成新的本地名称,如果遇到点号,就将点号全部替换,得到新的本地名称,再和域名部分拼接在一起,存入HashSet中,返回HashSetsize即可。

public int numUniqueEmails(String[] emails) {
    Set<String> set = new HashSet<String>();
    for (String email : emails) {
        String tem = email;
        int index = tem.indexOf('@');
        // 截取@之前的字符串
        tem = tem.substring(0, index);
        // 有'+',就再截取'+'号之前的字符串
        if (tem.indexOf('+') > 0) {
            tem = tem.substring(0, tem.indexOf('+'));
        }
        // 将所有点号替换
        tem = tem.replace(".", "");
        // 将@符号前的新字符串和原字符串@符号后的域名拼接
        // 存入HashSet
        set.add(tem+email.substring(index));
    }
    return set.size();
}


03 第二种解法

我们也可以不使用字符串截取、替换等方法,直接对字符进行判断,然后拼接成新的email地址,最后存入HashSet中,返回HashSetsize即可。

public int numUniqueEmails2(String[] emails) {
    Set<String> set = new HashSet<String>();
    for (String email : emails) {
        set.add(handleEmail(email));
    }
    return set.size();
}

public String handleEmail(String email) {
    StringBuilder sb = new StringBuilder();
    int n = email.length();
    // 是否遇到@符号
    boolean flag = false;
    for (int i=0; i<n; i++) {
        char c = email.charAt(i);
        if (!flag) {
            //没遇到@符号前,遇到.号一律 跳过
            if (c == '.') {
                continue;
            } 
            //遇到+号,往后跳一位,开始寻找@符号
            if (c == '+') {
                i++;
                while (i < n && email.charAt(i) != '@') {
                    i++;
                }
                c = email.charAt(i);
                // 已经遇到@符号
                flag = true;
            } else if(c == '@'){
                // 没遇到+号,却遇到@符号了
                flag = true;
            }
        }
        sb.append(c);
    }
    return sb.toString();
}


04 小结

算法专题目前已连续日更超过六个月,算法题文章224+篇,公众号对话框回复【数据结构与算法】、【算法】、【数据结构】中的任一关键词,获取系列文章合集。

以上就是全部内容,如果大家有什么好的解法思路、建议或者其他问题,可以下方留言交流,点赞、留言、转发就是对我最大的回报和支持!

posted @ 2019-06-17 08:43 程序员小川 阅读(...) 评论(...) 编辑 收藏