Problem 2437

Abstract / Summary

Count how many ways to fill in a clock time string so that it shows a valid time.

Note

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

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
11 lines | 390 bytes | submitted October 14, 2023 | GitHub   10% comment ratio | tab size 4 | low complexity

Difficulty

This problem is ranked as
easy medium hard

and has an acceptance rate of about 48% (80k+ submissions).

Typical patterns to solve this problem:
  • Enumeration
  • String
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 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 is 1 and the minute’s second digit is 5.
  • 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 be 4-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 replace call avoids repeated character-by-character processing.
  • Range iteration - Using range(24) and range(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.search directly, the underlying re module 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.

written by openai gpt

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.

written by google gemini

Code Quality

Several LLMs ranked my code quality on a scale from 1 (very poor) to 10 (outstanding):
n = 26 | median = 5 | μ = 5.23 | σ = 1.60

Complexity Analysis

Time: constant
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
generated automatically

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 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
20 links | 8 authors | 7 languages

Videos

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

Similar Problems

1 similar problem

Solved On The Same Day

6 solutions   October 14, 2023

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