给定一个段落 (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"不是最终的答案,虽然它出现次数更多,但它在禁用单词列表中。
class Solution {
public String mostCommonWord(String paragraph, String[] banned) {
Set<String> set = new HashSet<>();
for(String bannedWord : banned)
set.add(bannedWord.toLowerCase());//注意转为小写
Map<String,Integer> map = new HashMap<>();
int len = paragraph.length();
int i = 0;
//构造一个新的字符串,单词间用空格分隔 便于分割
StringBuffer sb = new StringBuffer();
while(i < len){
if(!isZiMu(paragraph.charAt(i))){
while(i < len && !isZiMu(paragraph.charAt(i)))
i++;
if(i != len)
sb.append(' ');
}else
sb.append(paragraph.charAt(i++));
}
String[] words = sb.toString().split(" ");
for(String word : words){
//转为小写
word = word.toLowerCase();
if(!set.contains(word)){
map.put(word,map.getOrDefault(word,0) + 1);
}
}
String key = null;
int max = 0;
for(String k : map.keySet()){
//System.out.println(k + " ");
if(map.get(k) > max){
max = map.get(k);
key = k;
}
}
return key;
}
//判断是否属于字母
private boolean isZiMu(Character c){
if(c >= 'A' && c <= 'Z')
return true;
if(c >= 'a' && c <= 'z')
return true;
return false;
}
}