Given a string s
, return whether s
is a valid number.
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"
.
Formally, a valid number is defined using one of the following definitions:
An integer number is defined with an optional sign '-'
or '+'
followed by digits.
A decimal number is defined with an optional sign '-'
or '+'
followed by one of the following definitions:
'.'
.'.'
followed by digits.'.'
followed by digits.An exponent is defined with an exponent notation 'e'
or 'E'
followed by an integer number.
The digits are defined as one or more digits.
Example 1:
Input: s = "0"
Output: true
Example 2:
Input: s = "e"
Output: false
Example 3:
Input: s = "."
Output: false
Constraints:
1 <= s.length <= 20
s
consists of only English letters (both uppercase and lowercase), digits (0-9
), plus '+'
, minus '-'
, or dot '.'
.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute-force approach involves meticulously checking every possible scenario to determine if a given string represents a valid number. It's like trying out every possible combination of rules and character placements until a valid number is found or all possibilities are exhausted.
Here's how the algorithm would work step-by-step:
def is_valid_number_brute_force(input_string):
string_length = len(input_string)
for i in range(string_length):
for j in range(i, string_length):
sub_string = input_string[i:j+1]
# Handle empty substring
if not sub_string:
continue
# Check if the substring is a valid number.
if is_valid_substring(sub_string):
return True
return False
def is_valid_substring(sub_string):
# Flags to track the presence of digits, exponent, and decimal
digit_seen = False
exponent_seen = False
decimal_seen = False
for i, char in enumerate(sub_string):
if char.isdigit():
digit_seen = True
elif char in ['+', '-']:
# Sign can only appear at the beginning or after 'e'
if i > 0 and sub_string[i-1] != 'e':
return False
if i == len(sub_string) - 1:
return False
elif char == '.':
# Decimal point can only appear once and before 'e'
if decimal_seen or exponent_seen:
return False
decimal_seen = True
elif char == 'e':
# Exponent can only appear once and must have a digit before it
if exponent_seen or not digit_seen:
return False
exponent_seen = True
digit_seen = False # Reset digit_seen for the part after 'e'
else:
# Invalid character
return False
# Must have seen at least one digit
return digit_seen
The challenge is to check if a given text string is a valid number, like checking if it's formatted correctly according to math rules. We'll go through the string one piece at a time, verifying that each part (numbers, signs, decimal points, exponents) fits the allowed patterns for a valid number.
Here's how the algorithm would work step-by-step:
def is_number(text):
text = text.strip()
string_length = len(text)
if string_length == 0:
return False
index = 0
if text[index] == '+' or text[index] == '-':
index += 1
if index == string_length:
return False
number_of_digits = 0
number_of_decimals = 0
while index < string_length and text[index].isdigit():
index += 1
number_of_digits += 1
if index < string_length and text[index] == '.':
index += 1
number_of_decimals += 1
# Decimal part is optional, but at least one digit must exist.
while index < string_length and text[index].isdigit():
index += 1
if number_of_digits == 0 and index - (number_of_decimals + number_of_digits) == 1:
return False
# An exponent can only show up once.
if index < string_length and (text[index] == 'e' or text[index] == 'E'):
index += 1
# Exponent sign is optional
if index < string_length and (text[index] == '+' or text[index] == '-'):
index += 1
exponent_digits = 0
while index < string_length and text[index].isdigit():
index += 1
exponent_digits += 1
# Exponent digits are required after 'e' or 'E'.
if exponent_digits == 0:
return False
# Check for remaining characters; if any exist, it's invalid.
if index < string_length:
return False
# If we reach this point, the number is valid.
return True
Case | How to Handle |
---|---|
Null or empty string input | Return false immediately as an empty string is not a valid number. |
String with only whitespace characters | Trim whitespace and return false if the resulting string is empty. |
Leading or trailing whitespace | Trim the string before processing to avoid incorrect parsing. |
Multiple signs (+/-) before a number or exponent | Handle only one sign character immediately before a number or exponent, and return false otherwise. |
Exponent without an integer or decimal before it | Return false, because there must be a number preceding the exponent. |
Decimal point without any digits before or after | Return false, because a decimal point must have at least one digit on either side to be valid in isolation. |
Integer overflow during parsing | Check for potential integer overflow during parsing by using long type and ensuring it does not exceed limits before cast to int. |
Floating-point precision issues | While this problem generally uses strings, be aware that if converting to float, compare results with tolerance in range of system precision. |