65. Valid Number
Your function receives a string s and must return true exactly when s spells a syntactically valid number, and false otherwise. No parsing library allowed — decide it character by character.
A valid number is a base part optionally followed by an exponent part:
- The base part is either an integer or a decimal, each allowed one leading + or - sign.
- An integer is one or more digits.
- A decimal contains exactly one dot . with digits on at least one side of it — so 4., .5, and 3.14 all qualify, but a lone . does not.
- The exponent part, if present, is the letter e or E followed by an integer (which may carry its own sign but never a dot).
Anything else — extra signs, a second dot, stray letters, an empty exponent — makes the whole string invalid. The string contains no whitespace.
Example 1:
Input: s = "0"
Output: true
Explanation: A single digit is a valid integer.
Example 2:
Input: s = "e"
Output: false
Explanation: There is no base part before the exponent marker and no integer after it.
Example 3:
Input: s = "-.9"
Output: true
Explanation: A sign, then a decimal with digits on the right side of the dot — a valid decimal.
Example 4:
Input: s = "99e2.5"
Output: false
Explanation: The exponent must be a plain integer; a dot after the e is never allowed.
Constraints:
- 1 ≤ s.length ≤ 20
- s consists only of English letters (upper or lower case), digits 0-9, plus '+', minus '-', and dot '.'.
- s contains no whitespace.
Hints:
Split the problem at the exponent marker: at most one 'e'/'E' may appear, the part before it must be a valid integer or decimal, and the part after it must be a valid integer. Validating those two small grammars separately is much easier than one giant condition.
For a single-pass alternative, track three flags while scanning: seen a digit, seen a dot, seen an exponent. A sign is legal only at position 0 or right after e/E; a dot is legal only before any e/E and only once; an e/E needs a digit before it and resets the digit flag so it can demand one after.
The final answer of the single pass is just the digit flag: every rejection happens mid-scan, and a string that survives is valid iff its last section actually contained a digit (catching "1e" and "+").
▶ Run checks these sample cases. Submit also runs hidden edge cases.
Input: s = "0"
Expected output: true