Scan letters into lowercase words, count non-banned tokens, and update the answer whenever a word reaches a new highest frequency.
Complexity
O(n + b) time and O(n + b) space.
Find the most frequent case-insensitive word that is not banned.
Scan letters into lowercase words, count non-banned tokens, and update the answer whenever a word reaches a new highest frequency.
O(n + b) time and O(n + b) space.
package main
import (
"strings"
"unicode"
)
func mostCommonWord(paragraph string, banned []string) string {
blocked := map[string]bool{}
for _, word := range banned {
blocked[word] = true
}
counts := map[string]int{}
answer, best := "", 0
words := strings.FieldsFunc(strings.ToLower(paragraph), func(character rune) bool { return !unicode.IsLetter(character) })
for _, word := range words {
if blocked[word] {
continue
}
counts[word]++
if counts[word] > best {
answer, best = word, counts[word]
}
}
return answer
}
import re
from collections import Counter
class Solution:
def mostCommonWord(self, paragraph: str, banned: list[str]) -> str:
blocked = set(banned)
counts = Counter(word for word in re.findall(r"[a-z]+", paragraph.lower()) if word not in blocked)
return counts.most_common(1)[0][0]
function mostCommonWord(paragraph: string, banned: string[]): string {
const blocked = new Set(banned.map((word) => word.toLowerCase()));
const counts = new Map<string, number>();
let answer = "";
let best = 0;
for (const word of paragraph.toLowerCase().match(/[a-z]+/g) ?? []) { if (blocked.has(word)) continue; const count = (counts.get(word) ?? 0) + 1; counts.set(word, count); if (count > best) { best = count; answer = word; } }
return answer;
}