LeetCode 3295: Report Spam Message (Hash Set + Early Stop Counting)
LeetCode 3295StringHash SetToday we solve LeetCode 3295 - Report Spam Message.
Source: https://leetcode.com/problems/report-spam-message/
English
Problem Summary
Given an array message and an array bannedWords, return true if at least 2 words in message appear in bannedWords; otherwise return false.
Key Insight
Membership query is the core operation. Put all banned words into a hash set, then scan message once and count matches. As soon as count reaches 2, we can return immediately.
Algorithm
- Build set(bannedWords).
- Initialize hits = 0.
- For each word in message, if it is in the set then increment hits.
- If hits >= 2, return true early; otherwise return false after loop.
Complexity Analysis
Let n = message.length, m = bannedWords.length.
Time: O(n + m) average.
Space: O(m).
Reference Implementations (Java / Go / C++ / Python / JavaScript)
import java.util.*;
class Solution {
public boolean reportSpam(String[] message, String[] bannedWords) {
Set<String> banned = new HashSet<>(Arrays.asList(bannedWords));
int hits = 0;
for (String w : message) {
if (banned.contains(w)) {
hits++;
if (hits >= 2) return true;
}
}
return false;
}
}func reportSpam(message []string, bannedWords []string) bool {
banned := make(map[string]struct{}, len(bannedWords))
for _, w := range bannedWords {
banned[w] = struct{}{}
}
hits := 0
for _, w := range message {
if _, ok := banned[w]; ok {
hits++
if hits >= 2 {
return true
}
}
}
return false
}class Solution {
public:
bool reportSpam(vector<string>& message, vector<string>& bannedWords) {
unordered_set<string> banned(bannedWords.begin(), bannedWords.end());
int hits = 0;
for (const string& w : message) {
if (banned.count(w)) {
++hits;
if (hits >= 2) return true;
}
}
return false;
}
};class Solution:
def reportSpam(self, message: List[str], bannedWords: List[str]) -> bool:
banned = set(bannedWords)
hits = 0
for w in message:
if w in banned:
hits += 1
if hits >= 2:
return True
return Falsevar reportSpam = function(message, bannedWords) {
const banned = new Set(bannedWords);
let hits = 0;
for (const w of message) {
if (banned.has(w)) {
hits += 1;
if (hits >= 2) return true;
}
}
return false;
};中文
题目概述
给定字符串数组 message 和 bannedWords。如果 message 中至少有 2 个单词出现在 bannedWords 里,返回 true;否则返回 false。
核心思路
关键是高效判断“某个单词是否在黑名单里”。把 bannedWords 放进哈希集合后,查询可做到均摊 O(1)。遍历 message 计数,达到 2 立即返回。
算法步骤
- 先构建 bannedWords 的哈希集合。
- 维护计数器 hits。
- 遍历 message:若当前词在集合中,hits++。
- 一旦 hits >= 2 直接返回 true;遍历结束仍不足 2 则返回 false。
复杂度分析
设 n = message.length,m = bannedWords.length。
时间复杂度:O(n + m)(均摊)。
空间复杂度:O(m)。
多语言参考实现(Java / Go / C++ / Python / JavaScript)
import java.util.*;
class Solution {
public boolean reportSpam(String[] message, String[] bannedWords) {
Set<String> banned = new HashSet<>(Arrays.asList(bannedWords));
int hits = 0;
for (String w : message) {
if (banned.contains(w)) {
hits++;
if (hits >= 2) return true;
}
}
return false;
}
}func reportSpam(message []string, bannedWords []string) bool {
banned := make(map[string]struct{}, len(bannedWords))
for _, w := range bannedWords {
banned[w] = struct{}{}
}
hits := 0
for _, w := range message {
if _, ok := banned[w]; ok {
hits++
if hits >= 2 {
return true
}
}
}
return false
}class Solution {
public:
bool reportSpam(vector<string>& message, vector<string>& bannedWords) {
unordered_set<string> banned(bannedWords.begin(), bannedWords.end());
int hits = 0;
for (const string& w : message) {
if (banned.count(w)) {
++hits;
if (hits >= 2) return true;
}
}
return false;
}
};class Solution:
def reportSpam(self, message: List[str], bannedWords: List[str]) -> bool:
banned = set(bannedWords)
hits = 0
for w in message:
if w in banned:
hits += 1
if hits >= 2:
return True
return Falsevar reportSpam = function(message, bannedWords) {
const banned = new Set(bannedWords);
let hits = 0;
for (const w of message) {
if (banned.has(w)) {
hits += 1;
if (hits >= 2) return true;
}
}
return false;
};
Comments