刷题日记 819. 最常见的单词

124 阅读1分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

一、题目描述:

819. 最常见的单词 - 力扣(LeetCode) (leetcode-cn.com)

给定一个段落 (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"不是最终的答案,虽然它出现次数更多,但它在禁用单词列表中。

提示:

  • 1 <= 段落长度 <= 1000
  • 0 <= 禁用单词个数 <= 100
  • 1 <= 禁用单词长度 <= 10
  • 答案是唯一的, 且都是小写字母 (即使在 paragraph 里是大写的,即使是一些特定的名词,答案都是小写的。)
  • paragraph 只包含字母、空格和下列标点符号!?',;.
  • 不存在没有连字符或者带有连字符的单词。
  • 单词里只包含字母,不会出现省略号或者其他标点符号。

二、思路分析:

思路很清晰,就是将句子切割成单词,转小写,然后统计每个不在禁止单词列表中的单词的出现次数,返回次数最高的单词。 为了高效检查单词是否被禁止,使用了集合Set对象;切割单词时,用了js的split方法,该方法支持正则表达式,将连续的空格或标点符号作为分隔符,即可正确分割单词

三、AC 代码:

/**
 * @param {string} paragraph
 * @param {string[]} banned
 * @return {string}
 */
var mostCommonWord = function(paragraph, banned) {
    var bannedSet = new Set();
    banned.forEach((v) => {
        bannedSet.add(v);
    });
    var ans = "";
    var count = new Map();
    paragraph.split(/[!\?',;\.' ]+/).forEach((v) => {// 根据标点符号或空格切割成多个单词,转小写,计数
        if (v == "") return;
        v = v.toLocaleLowerCase();
        if (bannedSet.has(v)) {
            return;
        }
        count.set(v, count.has(v) ? count.get(v) + 1 : 1);
    });
    let maxC = 0;
    [...count.entries()].forEach(([k, v]) => {// 找次数最多的单词
        if (maxC < v) {
            maxC = v;
            ans = k;
        }
    })
    return ans;
};