Problem 3120

Abstract / Summary

Count how many characters in a string are not letters or digits.

Note

The full problem description, including helpful examples, can be found on LeetCode.

Python 3120.py

class Solution:
    def numberOfSpecialChars(self, word: str) -> int:
        return sum([ chr(ord(c) + 32) in word for c in set(word) ])
3 lines | 141 bytes | submitted June 1, 2024 | GitHub   tab size 4 | low complexity

Difficulty

This problem is ranked as
easy medium hard

and has an acceptance rate of about 69% (100k+ submissions).
I solved 663 easy, 1250 medium and 309 hard problems

AI Disclaimer

Every single line of code was written by me, 100% from scratch, between August 2023 and August 2024.
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.
LeetCode profile | GitHub repo

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/chr with 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 in operator 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.

written by openai gpt

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.

written by google gemini

Code Quality

Several LLMs ranked my code quality on a scale from 1 (very poor) to 10 (outstanding):
n = 27 | median = 4 | μ = 4.74 | σ = 2.01

Complexity Analysis

not analyzed yet

Other Solutions

I wrote a basic crawler to find other solutions to that problem.
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++
20 links | 8 authors | 6 languages

Videos

5 videos   did my crawler come up with invalid videos ? drop me a line.

Similar Problems

2 similar problems

Solved On The Same Day

3 solutions   June 1, 2024

Extra

There are a few extra pages giving you some insights into my setup:
  • 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