Leetcode 65. Valid Number
Asked at:
Meta
DESCRIPTION
Determine whether a given string represents a valid numeric literal according to specific grammar rules. The literal consists of an optional sign (+ or -), followed by either an integer or decimal (formats like 123, 123., .123, or 123.456), and optionally an exponent part (e or E) with an optional sign and digits. For example, "-123.45e+6" is valid, but "123." with no digits before the dot, or "e5" with no base number, are invalid.
Input:
"123.45e-6"
Output:
true
Explanation: Valid decimal with exponent: integer part 123, decimal part 45, exponent -6
Constraints:
- String length: 1 ≤ s.length ≤ 1000
- String contains only digits, +, -, ., e, E, and whitespace
- Leading/trailing whitespace should be ignored
- At least one digit must appear before or after the decimal point
- Exponent part requires at least one digit after the sign
Understanding the Problem
The challenge lies in validating multiple optional components with interdependencies: a sign can only appear at the start or after e/E, a decimal point requires digits on at least one side, and an exponent requires both the e/E marker and subsequent digits. Edge cases include lone dots (.), incomplete exponents (1e), multiple decimal points (1.2.3), and invalid character placement (+-5, 1e+). A robust solution must track state transitions through the string, ensuring each character appears in a valid context.
Building Intuition
A naive approach might use multiple string splits or regex patterns, but this becomes error-prone with overlapping rules (e.g., distinguishing between the initial sign and exponent sign). A state machine approach is cleaner: track whether we've seen digits, a decimal point, or an exponent marker, and validate each character based on current state. For example, after seeing e, we must encounter an optional sign followed by digits, and no decimal point is allowed afterward.
Numeric literal validation is fundamental to compiler lexical analysis, JSON/XML parsers, and data validation systems. Understanding this pattern helps implement tokenizers, input sanitizers, and configuration file parsers that must distinguish valid numbers from malformed input.
Common Pitfalls
Implementation
State Tracking Variables
Initialize boolean flags to track what components we've encountered: seenDigit (at least one digit in current number part), seenDot (decimal point), and seenExponent (e/E marker). Also track seenDigitAfterExponent separately since the exponent requires its own digits. For example, when processing "123.45e-6", after the e we reset digit tracking to ensure the exponent part -6 has valid digits.
# State Tracking VariablesseenDigit = FalseseenDot = FalseseenExponent = FalseseenDigitAfterExponent = False
Character-by-Character Validation
Iterate through the trimmed string and validate each character based on current state. For digits, set seenDigit (and seenDigitAfterExponent if after e). For decimal points, ensure we haven't seen one already and we're not in the exponent part. For signs, verify we're at the start or immediately after e/E. For exponent markers, ensure we haven't seen one already and we have at least one digit in the base number. For example, in ".5e2", the dot is valid (no prior dot), 5 sets seenDigit, e is valid (digit exists), and 2 sets seenDigitAfterExponent.
# Character-by-Character Validationfor i, char in enumerate(s):if char.isdigit():seenDigit = Trueif seenExponent:seenDigitAfterExponent = Trueelif char == '.':if seenDot or seenExponent:return FalseseenDot = Trueelif char in 'eE':if seenExponent or not seenDigit:return FalseseenExponent = Trueelif char in '+-':if i != 0 and s[i-1] not in 'eE':return Falseelse:return False
Final Validation Check
After processing all characters, perform a final state check: ensure seenDigit is true (at least one digit in base number) and if seenExponent is true, ensure seenDigitAfterExponent is also true. This catches cases like "1e" (exponent marker without digits) or "." (no digits at all). Return true only if all conditions pass.
# Final Validation Checkif not seenDigit:return Falseif seenExponent and not seenDigitAfterExponent:return Falsereturn True
What We've Learned
- Pattern: State machine with boolean flags elegantly handles complex grammar rules with optional components
- Use Case: Apply this validation pattern to lexical analyzers, configuration parsers, and input sanitizers
- Edge Case Handling: Separate digit tracking for base and exponent parts prevents accepting incomplete exponents
- Whitespace: Always trim input before validation to handle leading/trailing spaces uniformly
Problems to Practice
easy
Both problems involve validating string formats against specific grammar rules. Valid Parentheses requires checking if brackets are properly matched and nested, which shares the pattern-matching and state-tracking aspects of validating numeric literals.
medium
This problem requires parsing a string with nested structures and handling different character types (digits, letters, brackets), similar to how Valid Number must parse and validate different components (signs, digits, decimals, exponents) in a specific grammar.
medium
While using a different approach, Decode Ways also involves validating whether a string follows specific numeric rules and handling edge cases around valid digit combinations, providing complementary practice in string validation with numeric constraints.
Question Timeline
See when this question was last asked and where, including any notes left by other candidates.
Late September, 2025
Senior
Leetcode 65. Valid Number But without the exponent condition. All the other conditions were valid.
Mid July, 2025
Meta
Manager
For example, all the following are valid numbers: "2", "0089", "-0.1", "+3.14", "4.", "-.9", "2e10", "-90E3", "3e+7", "+6e-1", "53.5e93", "-123.456e789", while the following are not valid numbers: "abc", "1a", "1e", "e3", "99e2.5", "--6", "-+3", "95a54e53".
Mid May, 2025
Meta
Mid-level
Comments
Hello Interview Premium
Your account is free and you can post anonymously if you choose.