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"不是最终的答案,虽然它出现次数更多,但它在禁用单词列表中。
题解:
注意:
不光要考虑
ball,
,这种情况,他还会出现a,b,c,d.
这种情况
func mostCommonWord(paragraph string, banned []string) string { // 将banned存入map,便于后续判断当前单词是否被ban bannedMap :=make(map[string]int) for _, s := range banned { bannedMap[s] = 0 } // 转小写 paragraph = strings.ToLower(paragraph) // 段落单词切片,除去标点符号 var wordSlice []string // 单个单词的字母切片 var cSlice []rune for i, c := range paragraph { if c >= 'a' && c <= 'z' { cSlice = append(cSlice, c) // 遍历到了最后 if i==len(paragraph)-1 { wordSlice = append(wordSlice, string(cSlice)) break } } else { // 遇到非字母字符,将上面的rune切片转成字符串存入单词切片 if string(cSlice) == " "||len(string(cSlice))==0 { cSlice = []rune{} continue } else { wordSlice = append(wordSlice, string(cSlice)) cSlice = []rune{} continue } } } // 已经出现过的单词的次数 already := make(map[string]int) max := 0 result := "" for _, word := range wordSlice { // 如果被ban 直接下一个单词 if _,ok:=bannedMap[word];ok==true { continue } // 如果不存在 加入map 次数初始化为1 if _, ok := already[word]; ok == false { already[word] = 1 }else { already[word]++ } if already[word] > max { max = already[word] result = word } } return result }