一起养成写作习惯!这是我参与「掘金日新计划 · 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;
}
}