算法小知识-----04.17-----最常见的单词

126 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第16天,点击查看活动详情

今天是周日,一开始所幸遇到的是简单题,谁知道做着做着发现不对劲,逐渐变成面向用例编码,果然最后打开LeetCode官方发现,差评还是很多的哈哈哈哈

最常见的单词

该题出自力扣的819题 —— 最常见的单词【简单题】,虽然我觉得并不简单

审题

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

  • 该题的题意相对简单,给出一个字符串,再给出一个禁用的字符串数组;找出在字符串中出现最多的字符串,并且不得在禁用数组中出现;其中需要注意的是,大小写忽略 + 字符串后紧跟的逗号等符号忽略 + 字符串之间用空格隔开
  • 解法:
    • 首先看到禁用数组,并且需要不出现在禁用数组中,那么就在最后必然会出现判断是否存在禁用数组中,所以就需要用HashMap或者Set去装载这个禁用数组
    • 因为字符串之间不仅使用空格隔开,而且还会有逗号等字符紧跟,所以直接遍历整个字符(s.toCharArray(),一开始还打算用split分割)
    • 利用题目的业务规则进行判断 是否为字母 + 是否为空格 + 忽略大小写
    • 最后再次遍历整个HashMap,寻找出现次数等于最大计数的单词,该单词即为最常见的单词。

编码

class Solution {
    public String mostCommonWord(String paragraph, String[] banned) {
        Set<String> set = new HashSet<>();
        for (String b : banned) set.add(b);
        char[] cs = paragraph.toCharArray();
        int n = cs.length;
        String ans = null;
        Map<String, Integer> map = new HashMap<>();
        for (int i = 0; i < n; ) {
            if (!Character.isLetter(cs[i]) && ++i >= 0) continue;
            int j = i;
            while (j < n && Character.isLetter(cs[j])) j++;
            String sub = paragraph.substring(i, j).toLowerCase();
            i = j + 1;
            if (set.contains(sub)) continue;
            map.put(sub, map.getOrDefault(sub, 0) + 1);
            if (ans == null || map.get(sub) > map.get(ans)) ans = sub;
        }
        return ans;
    }
}

image.png