title: Check if the Sentence Is Pangram slug: check-if-the-sentence-is-pangram difficulty: easy leetcode_id: 1832 leetcode_url: https://leetcode.com/problems/check-if-the-sentence-is-pangram/ categories: - strings - hash-tables patterns: - prefix-sum description: | 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*. constraints: | - `1 <= sentence.length <= 1000` - `sentence` consists of lowercase English letters. examples: - input: 'sentence = "thequickbrownfoxjumpsoverthelazydog"' output: "true" explanation: "sentence contains at least one of every letter of the English alphabet." - input: 'sentence = "leetcode"' output: "false" explanation: "The sentence only contains 5 unique letters: c, d, e, l, o, t. It's missing 21 letters." explanation: intuition: | Think of this problem like a checklist: you have 26 boxes, one for each letter of the alphabet from 'a' to 'z'. As you read through the sentence, you're checking off each letter you encounter. The question becomes: **after reading the entire sentence, have all 26 boxes been checked?** A **set** is the perfect data structure for this task. Sets automatically handle duplicates — if you add the same letter multiple times, it only appears once. So as you iterate through the sentence, you add each character to a set. At the end, if the set contains exactly 26 unique characters, you have a pangram. The key insight is that we don't care *how many times* each letter appears, just *whether* it appears at all. This makes the problem a simple membership check rather than a counting problem. approach: | We solve this using a **Set-Based Approach**: **Step 1: Create a set from the sentence** - Convert the sentence into a set of characters - This automatically removes duplicates, leaving only unique letters - In Python, this is as simple as `set(sentence)`   **Step 2: Check the size of the set** - If the set contains exactly 26 elements, every letter of the alphabet is present - Return `True` if `len(unique_chars) == 26`, otherwise `False`   This approach works because the problem guarantees the input contains only lowercase English letters. Since there are exactly 26 such letters, a set of size 26 means all letters are present. common_pitfalls: - title: Using a List Instead of a Set description: | A common mistake is to use a list to track seen characters and check membership with `if char not in seen_list`. While this works, it's inefficient. List membership checking is **O(n)** per operation, making the overall algorithm **O(n * m)** where m is the number of unique characters seen. With a set, membership checking is **O(1)** on average, keeping the algorithm at **O(n)**. For this problem's constraints (n <= 1000), the difference is negligible. But using sets is a good habit for larger inputs. wrong_approach: "List with linear membership checking" correct_approach: "Set with O(1) membership checking" - title: Hardcoding the Alphabet description: | Some solutions compare the set against a hardcoded string like `"abcdefghijklmnopqrstuvwxyz"`. While this works, it's error-prone (easy to miss or duplicate a letter) and less elegant. Since we know there are exactly 26 lowercase English letters and the input is guaranteed to contain only those letters, simply checking `len(set(sentence)) == 26` is cleaner and less bug-prone. wrong_approach: "Comparing against hardcoded alphabet string" correct_approach: "Check if set size equals 26" - title: Forgetting About Case Sensitivity description: | While this problem specifies lowercase-only input, in real-world pangram checking you'd need to handle mixed case. A sentence like "The Quick Brown Fox..." would fail if you don't convert to lowercase first. Always read the constraints carefully. Here, the guarantee of lowercase-only input simplifies our solution. key_takeaways: - "**Sets for uniqueness**: When you only care about *presence* (not count), sets provide O(1) lookup and automatic deduplication" - "**Know your alphabet**: The English alphabet has exactly 26 letters — this fixed constant enables the simple `len() == 26` check" - "**Read the constraints**: The lowercase-only guarantee eliminates the need for case conversion" - "**Pattern recognition**: This is a classic 'check completeness' pattern — useful for problems asking if all elements of a known set are present" time_complexity: "O(n). We iterate through each character in the sentence once to build the set, where n is the length of the sentence." space_complexity: "O(1). The set can contain at most 26 characters (the English alphabet), which is a constant regardless of input size." solutions: - approach_name: Set Conversion is_optimal: true code: | def check_if_pangram(sentence: str) -> bool: # Convert sentence to set of unique characters unique_chars = set(sentence) # Pangram if all 26 letters are present return len(unique_chars) == 26 explanation: | **Time Complexity:** O(n) — Single pass to build the set. **Space Complexity:** O(1) — At most 26 characters in the set. This is the most Pythonic solution. The `set()` constructor iterates through the string once, and checking the length is O(1). Clean, readable, and efficient. - approach_name: Boolean Array is_optimal: true code: | def check_if_pangram(sentence: str) -> bool: # Track which letters we've seen (index 0 = 'a', index 25 = 'z') seen = [False] * 26 for char in sentence: # Convert character to index: 'a' -> 0, 'b' -> 1, etc. index = ord(char) - ord('a') seen[index] = True # Pangram if all 26 positions are True return all(seen) explanation: | **Time Complexity:** O(n) — Single pass through the sentence. **Space Complexity:** O(1) — Fixed array of 26 booleans. This approach uses a boolean array instead of a set. It's useful to understand as it shows how to map characters to array indices using `ord()`. The `all()` function returns `True` only if every element is `True`. - approach_name: Bitmask is_optimal: true code: | def check_if_pangram(sentence: str) -> bool: # Use a 32-bit integer as a bitmask # Bit 0 represents 'a', bit 1 represents 'b', etc. seen = 0 for char in sentence: # Set the bit corresponding to this character bit_position = ord(char) - ord('a') seen |= (1 << bit_position) # Check if all 26 bits are set: 2^26 - 1 = 67108863 return seen == (1 << 26) - 1 explanation: | **Time Complexity:** O(n) — Single pass through the sentence. **Space Complexity:** O(1) — Single integer variable. This advanced technique uses bit manipulation to track seen letters. Each bit in the integer represents whether a letter has been seen. The expression `(1 << 26) - 1` creates a number with 26 one-bits, representing all letters present. This is the most space-efficient approach and demonstrates bitmasking patterns.