LeetCode-819 最常见的单词

题目

     给定一个段落 (paragraph) 和一个禁用单词列表 (banned)。返回出现次数最多,同时不在禁用列表中的单词。
题目保证至少有一个词不在禁用列表中,而且答案唯一。
禁用列表中的单词用小写字母表示,不含标点符号。段落中的单词不区分大小写。答案都是小写字母。

输入: 
paragraph = "Bob hit a ball, the hit BALL flew far after it was hit."
banned = ["hit"]
输出: "ball"
解释: 
"hit" 出现了3次,但它是一个禁用的单词。
"ball" 出现了2次 (同时没有其他单词出现2次),所以它是段落里出现次数最多的,且不在禁用列表中的单词。 
注意,所有这些单词在段落里不区分大小写,标点符号需要忽略(即使是紧挨着单词也忽略, 比如 "ball,"), 
"hit"不是最终的答案,虽然它出现次数更多,但它在禁用单词列表中。


自己想法:(哈希表+hashMap+遍历) 但这样用时比较慢

先创建一个哈希表,将banned中的每一个单词加进去, 然后利用正则表达式,将paragraph分割成一个个单词。再遍历分割后paragraph的String数组,看看是否存在于hashset中,若不在就加入hashMap并计数。

代码:

执行用时:21 ms, 在所有 Java 提交中击败了7.75%的用户
内存消耗:41.2 MB, 在所有 Java 提交中击败了50.24%的用户
通过测试用例:47 / 47
class Solution {
    public String mostCommonWord(String paragraph, String[] banned) {
        String regex = "[\\s\\p{Punct}]"; // \\s 空格符 p{Punct}标点符号
        String[] str = paragraph.split(regex); //分割字符串
        HashSet<String> hashSet = new HashSet<>();
        HashMap<String, Integer> hm = new HashMap<>();
        for (String ele : banned)
            hashSet.add(ele);  //加入禁用单词
        for (String words : str) {
            String word = words.toLowerCase(); //转成小写字母
            if (!word.equals("")&&!hashSet.contains(word)) {  //不包含
                hm.put(word, hm.getOrDefault(word, 0) + 1); //记录次数
            }
        }
        Set<String> strs = hm.keySet();
        int max=0;
        String s=null;
        for(String ele :strs) {
            if (hm.get(ele) > max) {
                max = hm.get(ele);
                s=ele;
            }
        }
        return s;
    }
}

在一开始的时候,判断不包含的条件中我只限制了哈希表if (!hashSet.contains(word))

但会发现一个问题:split(regex)——regex = "[\\s\\p{Punct}]"; // \\s 空格符 p{Punct}标点符号      会分割出“”(空字符串)【例如bob. hit  先遇到了. 分割为bob和“”】,这会导致后面遍历取最大值时出错。所以需要补上 if (!word.equals("")&&!hashSet.contains(word))


看了一下别人的题解,思路都差不多,发现这题的执行时间普遍比较久

优化一下:先对原字符串进行处理:

执行用时:13 ms, 在所有 Java 提交中击败了33.22%的用户

1.全部转为小写字母    2.将标点符号用“ ”代替    3.再进行分割

class Solution {
    public String mostCommonWord(String paragraph, String[] banned) {
        paragraph = paragraph.toLowerCase();
        paragraph = paragraph.replaceAll("\\p{Punct}"," ");//正则表达式  将所有标点符号使用 空格代替
        String[] words = paragraph.split(" ");
        
        HashMap<String,Integer> map = new HashMap<>();//存储 string-次数 键值对
        HashSet<String> bannedSet = new HashSet<>();
        for(String word:banned){
            bannedSet.add(word);
        }

        int max = 0;
        String maxWord = null;
        
        //记录对应的单词和出现次数
        for(String word : words){
            if(word == "") continue;
            if(map.containsKey(word)){
                map.put(word,map.get(word)+1);
            }else{
                map.put(word,1);
            }
            if(map.get(word) > max){
                if(!bannedSet.contains(word)){
                    maxWord=word;
                    max = map.get(word);
                }
            }
        }
        System.out.println(map);
        return maxWord;
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值