97. Valid Number
hardAsked at PlaidDetermine if a string represents a valid number (with signs, decimals, exponents). Plaid asks this as a finite-state-machine problem — exactly the shape they need when parsing transaction amounts from heterogeneous bank-feed formats.
By Alex Chen, Founder, InterviewChamp.AI · Last verified
Source citations
Public interview reports confirming this problem appears in Plaid loops.
- Glassdoor (2025)— Plaid backend onsite — bank-feed number parsing.
- LeetCode Discuss (2026)— Plaid FSM hard.
Problem
Given a string s, return whether s is a valid number. A valid number can be split into these components (in order): A decimal number (with optional sign and decimal point) optionally followed by an exponent ('e' or 'E' followed by an integer with optional sign).
Constraints
1 <= s.length <= 20s consists of only English letters (both uppercase and lowercase), digits (0-9), plus '+', minus '-', or dot '.'.
Examples
Example 1
s = "0"trueExample 2
s = "e"falseExample 3
s = "."falseExample 4
s = "-1E-16"trueApproaches
1. Try Number()
JS's Number coercion.
- Time
- O(n)
- Space
- O(1)
function isNumber(s) { return s.trim() !== '' && !isNaN(Number(s)); }Tradeoff: Accepts 'Infinity' and 'NaN' which the spec disallows. Misses the LC-strict definition.
2. Finite-state machine
Track seen-digit, seen-dot, seen-exp, seen-digit-after-exp. Walk and update flags; reject on illegal transitions.
- Time
- O(n)
- Space
- O(1)
function isNumber(s) {
let seenDigit = false, seenDot = false, seenExp = false, digitAfterExp = true;
for (let i = 0; i < s.length; i++) {
const c = s[i];
if (c >= '0' && c <= '9') { seenDigit = true; digitAfterExp = true; }
else if (c === '+' || c === '-') {
if (i > 0 && s[i - 1] !== 'e' && s[i - 1] !== 'E') return false;
} else if (c === '.') {
if (seenDot || seenExp) return false;
seenDot = true;
} else if (c === 'e' || c === 'E') {
if (seenExp || !seenDigit) return false;
seenExp = true; digitAfterExp = false;
} else return false;
}
return seenDigit && digitAfterExp;
}Tradeoff: Compact FSM. The four flags encode the state cleanly.
Plaid-specific tips
Plaid grades this on whether you spot it as an FSM. Bonus signal: enumerate the edge cases out loud — empty exponent, leading dot without digits, sign in the middle. Connect to bank-feed parsing where institutions use heterogeneous number formats ('1,234.56', '1.234,56', '1.234e3').
Common mistakes
- Allowing 'e' or 'E' without a preceding digit (e.g., '.e1' or 'e3').
- Allowing '.' inside the exponent.
- Not requiring at least one digit after 'e'.
Follow-up questions
An interviewer at Plaid may pivot to one of these next:
- Parse a number that may contain commas or other thousand-separators.
- Parse currency-formatted numbers ($1,234.56).
- Parse a stream of mixed-format numbers and convert to canonical.
Solve it now
Free. No sign-up. Python and JavaScript run instantly in your browser.
FAQ
Why FSM over regex?
Regex works but obscures the state. FSM makes 'what's allowed next' explicit, which is easier to extend (e.g., to support comma separators).
What about 'inf' or 'NaN'?
Not allowed by the LC spec. The character-by-character FSM rejects them naturally because 'i' and 'n' aren't in the allowed set.
Practice these live with InterviewChamp.AI
Drill Valid Number and other Plaid interview questions under real-loop conditions with instant feedback on your reasoning, complexity claims, and code.
Practice these live with InterviewChamp.AI →