{x}
blog image

Check if the Sentence Is Pangram

A pangram is a sentence where every letter of the English alphabet appears at least once.

Given a string sentence containing only lowercase English letters, return true if sentence is a pangram, or false otherwise.

 

Example 1:

Input: sentence = "thequickbrownfoxjumpsoverthelazydog"
Output: true
Explanation: sentence contains at least one of every letter of the English alphabet.

Example 2:

Input: sentence = "leetcode"
Output: false

 

Constraints:

  • 1 <= sentence.length <= 1000
  • sentence consists of lowercase English letters.

Solution Explanation for Check if the Sentence Is Pangram

This problem asks whether a given sentence is a pangram—a sentence containing every letter of the alphabet at least once. We can solve this efficiently using a few different approaches.

Approach 1: Using a Set (or Hash Table)

This is the most straightforward approach. We leverage a set (or HashSet in Java, etc.) to store the unique characters encountered in the sentence. Sets provide efficient lookups (checking for existence takes O(1) on average).

Algorithm:

  1. Initialize a set: Create an empty set to store unique characters.
  2. Iterate through the sentence: For each character in the input sentence:
    • Add the character to the set.
  3. Check the set's size: After processing all characters, check if the size of the set is 26. If it is, the sentence contains all 26 letters of the alphabet, and we return true; otherwise, return false.

Time Complexity: O(n), where n is the length of the sentence. Iterating through the sentence takes O(n) time. Set operations (adding and checking size) are typically O(1) on average.

Space Complexity: O(1). The set will store at most 26 unique characters, so the space used is constant.

Code Examples:

Python:

class Solution:
    def checkIfPangram(self, sentence: str) -> bool:
        return len(set(sentence)) == 26

Java:

class Solution {
    public boolean checkIfPangram(String sentence) {
        Set<Character> uniqueChars = new HashSet<>();
        for (char c : sentence.toCharArray()) {
            uniqueChars.add(c);
        }
        return uniqueChars.size() == 26;
    }
}

C++:

class Solution {
public:
    bool checkIfPangram(string sentence) {
        unordered_set<char> uniqueChars;
        for (char c : sentence) {
            uniqueChars.insert(c);
        }
        return uniqueChars.size() == 26;
    }
};

Approach 2: Using a Bitmask

This approach is more concise and potentially slightly faster due to the use of bit manipulation. We use a single integer (mask) to represent the presence or absence of each letter. Each bit in the integer corresponds to a letter of the alphabet (e.g., bit 0 for 'a', bit 1 for 'b', etc.).

Algorithm:

  1. Initialize a bitmask: Start with mask = 0.
  2. Iterate through the sentence: For each character c:
    • Calculate the bit position: pos = c - 'a'.
    • Set the bit at position pos in mask using a bitwise OR operation: mask |= (1 << pos).
  3. Check the bitmask: After processing all characters, check if mask is equal to (1 << 26) - 1. This value represents a bitmask with all 26 bits set to 1.

Time Complexity: O(n). Similar to Approach 1, the dominant factor is the iteration through the sentence. Bitwise operations are very fast.

Space Complexity: O(1). We only use a single integer variable.

Code Examples:

Python:

class Solution:
    def checkIfPangram(self, sentence: str) -> bool:
        mask = 0
        for c in sentence:
            mask |= 1 << (ord(c) - ord('a'))
        return mask == (1 << 26) - 1

Java:

class Solution {
    public boolean checkIfPangram(String sentence) {
        int mask = 0;
        for (char c : sentence.toCharArray()) {
            mask |= (1 << (c - 'a'));
        }
        return mask == ((1 << 26) - 1);
    }
}

C++:

class Solution {
public:
    bool checkIfPangram(string sentence) {
        int mask = 0;
        for (char c : sentence) {
            mask |= (1 << (c - 'a'));
        }
        return mask == ((1 << 26) - 1);
    }
};

Both approaches are efficient and correct. The choice between them often comes down to personal preference and coding style. The bitmask approach might be slightly faster in some cases, but the set-based approach is generally easier to understand and maintain.