Python 2437.py
class Solution:
def countTime(self, time: str) -> int:
# once again: brute force
regex = time.replace("?", ".")
matches = 0
for hour in range(24):
for minute in range(60):
timestamp = f"{hour:02d}:{minute:02d}"
if re.search(regex, timestamp):
matches += 1
return matches
Difficulty
and has an acceptance rate of about 48% (80k+ submissions).
Typical patterns to solve this problem:
- Enumeration
- String
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 Solution class implements a method countTime that determines how many valid 24-hour timestamps can be formed from a pattern string containing digits and the wildcard character ?. The algorithm enumerates every possible hour (0-23) and minute (0-59), builds a concrete timestamp string, and checks whether it matches the pattern after converting the wildcards into a regular-expression fragment. The final count of matching timestamps is returned.
Core Logic
Pattern conversion
The first operation transforms the input pattern by replacing each ? with a dot (.), which in regular-expression syntax matches any single character. This creates a simple regex that can be applied to fully-specified timestamps.
regex = time.replace("?", ".")
Exhaustive enumeration
Two nested loops iterate over the complete set of hour and minute values permitted by a 24-hour clock. The outer loop runs from 0 to 23 inclusive, while the inner loop runs from 0 to 59 inclusive.
for hour in range(24):
for minute in range(60):
...
Timestamp construction
Inside the nested loops, the current hour and minute values are formatted into a zero-padded two-digit representation and concatenated with a colon to produce a canonical timestamp string such as "07:05" or "23:59".
timestamp = f"{hour:02d}:{minute:02d}"
Matching against the pattern
The constructed timestamp is tested against the previously built regular expression using re.search. If the pattern matches, the matches counter is incremented.
if re.search(regex, timestamp):
matches += 1
Result return
After all combinations have been examined, the method returns the total number of timestamps that satisfy the pattern.
return matches
Edge Cases Handled
The implementation naturally accommodates several edge conditions:
- Full wildcard pattern - When the input consists solely of
?characters (e.g.,"??:??"), the conversion yields"..:..". The regular expression matches every possible timestamp, and the loops count all 1440 valid times. - Partial wildcards - Patterns like
"1?:?5"replace only the specified?positions, allowing the algorithm to correctly match timestamps where the first hour digit is1and the minute’s second digit is5. - Leading zeros - The formatting step forces both hour and minute components to two digits, ensuring that timestamps such as
"03:07"are represented with leading zeros, which aligns with the expected pattern format. - Invalid hour or minute digits in the pattern - If the pattern contains a digit that cannot appear in any valid hour or minute (e.g.,
"2?:6?"where the second hour digit cannot be4-9), the regular expression will simply never match those combinations, and the count will correctly reflect zero matches for those positions.
Performance Optimizations Observed
The code leverages several built-in language features that contribute to efficient execution:
- String replacement - Converting the pattern to a regular expression with a single
replacecall avoids repeated character-by-character processing. - Range iteration - Using
range(24)andrange(60)provides fast, memory-light iteration over the fixed sets of hour and minute values. - Formatted string literals - The
f"{hour:02d}:{minute:02d}"expression constructs the timestamp in a single operation, avoiding concatenation of multiple intermediate strings. - Compiled regular-expression engine - Although the code calls
re.searchdirectly, the underlyingremodule caches compiled patterns, which reduces overhead for repeated matches against the same pattern.
These choices keep the inner loop lightweight, allowing the exhaustive search to complete quickly despite examining every possible timestamp.
ELI5 - Simplified Explanation
Imagine you have a magic clock that has some missing numbers shown as question marks. The code acts like a detective trying to figure out how many possible times could be hiding behind those question marks. First, it looks at the time string and changes every question mark into a little placeholder that can match any number. Then, the code starts a game of hide and seek by checking every single minute of the entire day, from zero hours and zero minutes all the way up to twenty-three hours and fifty-nine minutes. For every minute it checks, it writes down that time in a special format that always uses two digits. If that time matches the pattern with the placeholders, the detective adds one to a special pile called matches. By the time the code finishes checking every possibility, the pile contains the total count of valid times that could fit the original description.
Code Quality
Complexity Analysis
As a rule of thumb, the maximum input size for one second execution time is
- factorial: up to 10 elements
- exponential: up to 20 elements
- polynomial: a few thousand elements
- loglinear: up to 100,000 elements
- linear: a few million elements
- logarithmic: a billion elements
- constant: practically unlimited
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 | Python | Java | C++ | TS | |||
| WalkCCC | Python | Java | C++ | |||||
| leetcode.ca | Python | Java | C++ | Go | Rust | TS | ||
| Progiez | Python | Java | C++ | |||||
| github | charles-wangkai | Java | ||||||
| fsq | C++ | |||||||
| JoshCrozier | JS | |||||||
| lkwq007 | Python | |||||||
| 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++ | |||||||
| JoshCrozier | JavaScript | |||||||
| lkwq007 | Python |
Videos
Similar Problems
- problem 1736: Latest Time by Replacing Hidden Digits
Solved On The Same Day
- problem 830: Positions of Large Groups
- problem 1566: Detect Pattern of Length M Repeated K or More Times
- problem 1015: Smallest Integer Divisible by K
- problem 1016: Binary String With Substrings Representing 1 To N
- problem 1254: Number of Closed Islands
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