Facebook Pixel

3295. Report Spam Message

MediumArrayHash TableString
Leetcode Link

Problem Description

You are given an array of strings message and an array of strings bannedWords.

An array of words is considered spam if there are at least two words in it that exactly match any word in bannedWords.

Return true if the array message is spam, and false otherwise.

Intuition

The problem requires determining if a message contains at least two occurrences of words that are present in the bannedWords list. To achieve this efficiently, we utilize a hash table (implemented as a set in Python) to store the words from bannedWords. This allows for O(1) average time complexity for checking the presence of words from message in the bannedWords.

The solution involves iterating through each word in the message and checking if it exists in the banned words set. By maintaining a count of how many words from message are found in this set, we can ascertain if the message contains enough banned words to be classified as spam. If the count reaches two or more during this iteration, the message is deemed spam, and we return true. Otherwise, we conclude that it is not spam and return false.

Solution Approach

The solution employs a hash table to efficiently check for the presence of banned words in the message. The key steps in the approach are as follows:

  1. Initialize the Data Structure:

    • Convert the bannedWords list into a set s. This conversion leverages the set's property of average O(1) time complexity for membership checks, making it ideal for this task.
  2. Iterate Through the Message:

    • Traverse each word in the message array.
    • For each word, use the set membership operation to check if it exists in the set s. Specifically, w in s will return True if the word w from message is in the bannedWords set.
  3. Count and Decision:

    • Count the number of words in message that appear in the set s. This is accomplished using a generator expression within the sum function: sum(w in s for w in message).
    • Compare this count against the threshold of 2. If the count is greater than or equal to 2, return True indicating the message is spam. Otherwise, return False.

The code implementation encapsulating this logic is succinctly represented by:

class Solution:
    def reportSpam(self, message: List[str], bannedWords: List[str]) -> bool:
        s = set(bannedWords)
        return sum(w in s for w in message) >= 2

The approach efficiently determines if a message should be classified as spam by leveraging the properties of sets for fast lookup, thereby ensuring the solution is optimal.

Ready to land your dream job?

Unlock your dream job with a 2-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's consider a small example to illustrate the solution approach:

Suppose we have the following arrays:

  • message: ["free", "win", "prize", "money", "win"]
  • bannedWords: ["win", "free", "offer"]

Our objective is to determine if the message should be considered spam by checking if it has at least two words matching those in bannedWords.

  1. Initialize the Data Structure:

    • Convert bannedWords into a set s: s = {"win", "free", "offer"}.
  2. Iterate Through the Message:

    • Traverse each word in the message. For each word, check if it exists in set s:
      • "free" → present in s (count=1)
      • "win" → present in s (count=2)
      • "prize" → not in s
      • "money" → not in s
      • "win" → present in s
  3. Count and Decision:

    • Count the number of words from message present in s. In our case, this count is 3, which exceeds the threshold of 2.
    • Since the count is greater than or equal to 2, the function will return True, indicating the message is spam.

The above example demonstrates the solution's efficiency in determining spam status by utilizing set membership checks, ultimately classifying the message as spam.

Solution Implementation

1from typing import List
2
3class Solution:
4    def reportSpam(self, message: List[str], bannedWords: List[str]) -> bool:
5        # Convert bannedWords list into a set for O(1) average-time complexity in membership tests
6        banned_set = set(bannedWords)
7      
8        # Use a generator expression to count how many words in 'message' appear in 'banned_set'
9        banned_count = sum(word in banned_set for word in message)
10      
11        # Return True if two or more banned words are present in the message
12        return banned_count >= 2
13
1import java.util.HashSet;
2import java.util.Set;
3
4class Solution {
5    public boolean reportSpam(String[] message, String[] bannedWords) {
6        Set<String> bannedWordsSet = new HashSet<>();
7
8        // Add each banned word to the set
9        for (String word : bannedWords) {
10            bannedWordsSet.add(word);
11        }
12
13        int count = 0;
14
15        // Iterate through each word in the message
16        for (String word : message) {
17            // Check if the word is a banned word
18            if (bannedWordsSet.contains(word)) {
19                // Increment the count of banned words found
20                count++;
21
22                // If two or more banned words are found, return true
23                if (count >= 2) {
24                    return true;
25                }
26            }
27        }
28
29        // Return false if less than two banned words are found
30        return false;
31    }
32}
33
1#include <vector>
2#include <string>
3#include <unordered_set>
4
5class Solution {
6public:
7    // Function to determine if a message is considered spam
8    bool reportSpam(std::vector<std::string>& message, std::vector<std::string>& bannedWords) {
9        // Create a set from the list of banned words for quick lookup
10        std::unordered_set<std::string> bannedSet(bannedWords.begin(), bannedWords.end());
11        int count = 0;
12      
13        // Iterate through each word in the message
14        for (const auto& word : message) {
15            // Check if the word is in the set of banned words
16            if (bannedSet.find(word) != bannedSet.end()) {
17                ++count; // Increment the count for each banned word found
18              
19                // If two or more banned words are found, the message is spam
20                if (count >= 2) {
21                    return true;
22                }
23            }
24        }
25      
26        // If less than two banned words are found, the message is not spam
27        return false;
28    }
29};
30
1// Function to check if a message contains at least two banned words
2function reportSpam(message: string[], bannedWords: string[]): boolean {
3    // Convert the array of banned words into a Set for quick lookup
4    const bannedWordsSet = new Set<string>(bannedWords);
5
6    // Counter to keep track of how many banned words are found in the message
7    let bannedWordsCount = 0;
8
9    // Iterate through each word in the message
10    for (const word of message) {
11        // If the word is in the set of banned words
12        if (bannedWordsSet.has(word)) {
13            // Increment the counter
14            bannedWordsCount++;
15
16            // If we have found at least two banned words, return true
17            if (bannedWordsCount >= 2) {
18                return true;
19            }
20        }
21    }
22
23    // Return false if fewer than two banned words were found
24    return false;
25}
26

Time and Space Complexity

The time complexity of the code is O(n * m * |w|). This is because for each word in the message list of length n, we check for its presence in the set s, which contains m banned words. Each of these checks (in the worst-case) involves comparing words, which might entail examining all characters of maximum length |w|.

The space complexity is O(m * |w|). This arises from storing the bannedWords in a set, where m is the number of banned words and |w| is the maximum length of these words.

Learn more about how to find time and space complexity quickly.


Discover Your Strengths and Weaknesses: Take Our 2-Minute Quiz to Tailor Your Study Plan:
Question 1 out of 10

Which type of traversal does breadth first search do?


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!


Load More