65/670

65. Valid Number

Hard

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