Valid Number
Problem
Decide if a given string is a valid number. A valid number is an optional sign, then an integer or decimal, optionally followed by an exponent (e/E) with an optional sign and an integer.
s = "-90E3"truedef is_number(s):
seen_digit = seen_dot = seen_e = False
digit_after_e = True
for i, c in enumerate(s):
if c.isdigit():
seen_digit = True
digit_after_e = True
elif c in "+-":
if i > 0 and s[i-1] not in "eE": return False
elif c == ".":
if seen_dot or seen_e: return False
seen_dot = True
elif c in "eE":
if seen_e or not seen_digit: return False
seen_e = True
digit_after_e = False
else:
return False
return seen_digit and digit_after_e
function isNumber(s) {
let seenDigit = false, seenDot = false, seenE = false, digitAfterE = true;
for (let i = 0; i < s.length; i++) {
const c = s[i];
if (c >= "0" && c <= "9") { seenDigit = true; digitAfterE = true; }
else if (c === "+" || c === "-") {
if (i > 0 && s[i - 1] !== "e" && s[i - 1] !== "E") return false;
} else if (c === ".") {
if (seenDot || seenE) return false;
seenDot = true;
} else if (c === "e" || c === "E") {
if (seenE || !seenDigit) return false;
seenE = true; digitAfterE = false;
} else return false;
}
return seenDigit && digitAfterE;
}
class Solution {
public boolean isNumber(String s) {
boolean seenDigit = false, seenDot = false, seenE = false, digitAfterE = true;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (Character.isDigit(c)) { seenDigit = true; digitAfterE = true; }
else if (c == '+' || c == '-') {
if (i > 0 && s.charAt(i - 1) != 'e' && s.charAt(i - 1) != 'E') return false;
} else if (c == '.') {
if (seenDot || seenE) return false;
seenDot = true;
} else if (c == 'e' || c == 'E') {
if (seenE || !seenDigit) return false;
seenE = true; digitAfterE = false;
} else return false;
}
return seenDigit && digitAfterE;
}
}
bool isNumber(string s) {
bool seenDigit = false, seenDot = false, seenE = false, digitAfterE = true;
for (int i = 0; i < (int)s.size(); i++) {
char c = s[i];
if (isdigit(c)) { seenDigit = true; digitAfterE = true; }
else if (c == '+' || c == '-') {
if (i > 0 && s[i - 1] != 'e' && s[i - 1] != 'E') return false;
} else if (c == '.') {
if (seenDot || seenE) return false;
seenDot = true;
} else if (c == 'e' || c == 'E') {
if (seenE || !seenDigit) return false;
seenE = true; digitAfterE = false;
} else return false;
}
return seenDigit && digitAfterE;
}
Explanation
Deciding if a string is a valid number is tricky because there are many rules at once: an optional sign, digits, at most one decimal point, and an optional exponent. The trick is to make one pass while remembering a few flags about what we have seen so far.
We track seen_digit, seen_dot, seen_e, and digit_after_e. For each character we ask which category it falls in and check it against the rules using those flags.
The rules are simple per character: a digit sets seen_digit and digit_after_e to true; a sign is only legal at the very start or right after an e/E; a dot is illegal if we already saw a dot or an exponent; and an e/E needs a digit before it and must not repeat. Anything else fails immediately.
At the very end the number is valid only if we saw at least one digit (seen_digit) and, if there was an exponent, a digit came after it (digit_after_e). This catches cases like "e9" or "3e".
Example: "-90E3". The - is fine at position 0; 9 and 0 set seen_digit; E is valid because a digit came before it and sets digit_after_e=false; then 3 turns it back true. We finish with both required flags true, so the answer is true.