Python 3120.py
class Solution:
def numberOfSpecialChars(self, word: str) -> int:
return sum([ chr(ord(c) + 32) in word for c in set(word) ])
Difficulty
and has an acceptance rate of about 69% (100k+ submissions).
AI Disclaimer
However, two years later I set up this website and used various AI tools to generate most of the walkthrough / explanations below.
See this dedicated page for more details.
Code Walkthrough
Overview
The provided implementation defines a single method numberOfSpecialChars that receives a string word and returns an integer. The method counts how many distinct alphabetic characters appear in both uppercase and lowercase forms within the input. The logic is compact, relying on Python’s built-in collection types and arithmetic on character codes.
Key Steps
The core of the algorithm can be broken down into three conceptual operations, each reflected in a concise code fragment.
Creating a collection of unique characters
set(word)
By converting the input string to a set, the method eliminates duplicate characters. This ensures that each character is examined at most once, preventing redundant work when the same letter occurs many times.
Deriving the lowercase counterpart via ASCII arithmetic
chr(ord(c) + 32)
For any character c, the expression obtains its Unicode code point with ord, adds 32, and converts the result back to a character with chr. In the ASCII range, adding 32 to an uppercase letter yields its lowercase equivalent (e.g., 'A' → 'a'). This arithmetic avoids the overhead of calling the higher-level str.lower() method.
Testing for the presence of the lowercase form
chr(ord(c) + 32) in word
The membership test checks whether the derived lowercase character exists anywhere in the original string. Because word is a plain string, the in operator performs a linear scan, but this scan is executed only for the distinct characters identified earlier.
Aggregating the results
sum([ chr(ord(c) + 32) in word for c in set(word) ])
A list comprehension builds a sequence of Boolean values-True when the lowercase counterpart is found, False otherwise. The sum function treats True as 1 and False as 0, producing the final count of special characters.
Edge Cases Handled
When the input string is empty, set(word) yields an empty set, the list comprehension produces no elements, and sum returns 0. This correctly reflects that there are no special characters.
If the string contains only lowercase letters, the ASCII arithmetic transforms each lowercase character into a non-alphabetic symbol (e.g., 'a' → '{'). Since such symbols are unlikely to be present in the original string, the membership test evaluates to False for every entry, resulting in a count of 0.
Conversely, when the string consists solely of uppercase letters, the derived lowercase forms may be present if the original string also includes the matching lowercase letters. The algorithm correctly identifies each uppercase letter whose lowercase partner appears, regardless of the order or frequency of occurrences.
Non-alphabetic characters (digits, punctuation, whitespace) are also processed by the same steps. Adding 32 to their code points yields other characters that are typically absent from the original string, so they contribute False to the sum. This behavior naturally excludes them from the special-character count without requiring explicit checks.
Repeated occurrences of the same letter, whether in one case or both, do not affect the result because the set eliminates duplicates before the membership test is performed.
Performance Optimizations
The method’s design incorporates several implicit optimizations:
-
Deduplication via a set reduces the number of membership checks from potentially
len(word)to the number of distinct characters, which is bounded by 52 for English letters. This dramatically cuts work for long strings with many repeated characters. -
Direct ASCII manipulation (
ord/chrwith a constant offset) sidesteps the overhead of locale-aware case conversion functions. The arithmetic operation is O(1) and executed only for the unique characters. -
Built-in aggregation (
sum) leverages highly optimized C-level loops inside the Python interpreter, providing faster execution than a manual Python loop. -
Short-circuit evaluation is inherent in the membership test: as soon as a matching character is found, the
inoperator stops scanning the remainder of the string for that particular check.
Collectively, these choices keep the runtime proportional to the size of the input string while minimizing constant-factor costs, making the solution well-suited for large inputs.
ELI5 - Simplified Explanation
Imagine the computer is looking at a big box filled with letter blocks. Some of the letters are tall like giants, and some are small like little helpers. This code goes through all the unique letters in the box. It checks if the giant version of a letter is hanging out with its own tiny little helper. If the computer finds both the big one and the small one for the same letter, it marks that as a special pair. The code keeps counting all these special pairs until it has checked every single letter in the entire box.
Code Quality
Complexity Analysis
Other Solutions
Obviously, I did that after I solved the problem myself.
In general, AlgoMonster and WalkCCC solutions are high-quality and always worth a look.
I haven't checked most of the other solutions, but they might be helpful as well.
And of course, the LeetCode forum is always a good place (or even the best) to look for alternative approaches.
(click on a column header to sort the table)
| author | |||||||
|---|---|---|---|---|---|---|---|
| author | solutions | ||||||
| www | AlgoMonster | Java | C++ | Python | TS | ||
| WalkCCC | Java | C++ | Python | ||||
| leetcode.ca | Java | C++ | Go | Python | Rust | TS | |
| Progiez | Java | C++ | Python | ||||
| github | charles-wangkai | Java | |||||
| fsq | C++ | ||||||
| varunu28 | Java | ||||||
| withaarzoo | C++ | ||||||
| AlgoMonster | C++, Python, Java, TypeScript | ||||||
| WalkCCC | C++, Python, Java | ||||||
| leetcode.ca | C++, Go, Java, Python, Rust, TypeScript | ||||||
| Progiez | C++, Java, Python | ||||||
| charles-wangkai | Java | ||||||
| fsq | C++ | ||||||
| varunu28 | Java | ||||||
| withaarzoo | C++ |
Videos
Similar Problems
- problem 2309: Greatest English Letter in Upper and Lower Case
- problem 3121: Count the Number of Special Characters II
Solved On The Same Day
- problem 2468: Split Message Based on Limit
- problem 2472: Maximum Number of Non-overlapping Palindrome Substrings
Extra
- Tech Stack - my development environment and tools
- AI - how AI helped me create this website (NOT solving the problems)
- Progress - progression over time
- Quality - code quality