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.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.
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:
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;
}
};
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:
mask = 0
.c
:
pos = c - 'a'
.pos
in mask
using a bitwise OR operation: mask |= (1 << pos)
.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.