Problem

A valid number can be split up into these components (in order):

  1. A decimal number or an integer.
  2. (Optional) An 'e' or 'E', followed by an integer.

A decimal number can be split up into these components (in order):

  1. (Optional) A sign character (either '+' or '-').
  2. One of the following formats:
    1. One or more digits, followed by a dot '.'.
    2. One or more digits, followed by a dot '.', followed by one or more digits.
    3. A dot '.', followed by one or more digits.

An integer can be split up into these components (in order):

  1. (Optional) A sign character (either '+' or '-').
  2. One or more digits.

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"].

Given a string s, return true if s is a valid number.

Examples

Example 1:

Input: s = "0"
Output: true

Example 2:

Input: s = "e"
Output: false

Example 3:

Input: s = "."
Output: false

Solution

Method 1 - Using regex

To determine if a given string is a valid number according to the defined rules, we can use a finite state machine (FSM) or regular expressions (regex) to simplify the validation process.

Approach and Reasoning

  1. Regex: Using a regular expression we can succinctly capture all the formatting rules defined for a valid number.
  2. Components:
    • A regular expression will be designed to match: an optional sign, followed by digits and/or a decimal point, followed optionally by an exponent part.
  3. Validation:
    • We’ll create a pattern that encapsulates the entirety of the valid number.

Regular Expression Components

  • [-+]? - Matches an optional sign.
  • (\\d+\\.?|\\.\\d+|\\d+\\.\\d+) - Matches a decimal number.
  • ([eE][-+]?\\d+)? - Matches the optional exponent part.
Combined Regex
  • [-+]?((\\d+\\.?|\\.\\d+|\\d+\\.\\d+)([eE][-+]?\\d+)?)

Code

Java
class Solution {
    public boolean isNumber(String s) {
        String pattern = "[-+]?((\\d+\\.?|\\.\\d+|\\d+\\.\\d+)([eE][-+]?\\d+)?)";
        Pattern compiledPattern = Pattern.compile(pattern);
        Matcher matcher = compiledPattern.matcher(s.trim());
        return matcher.matches();
    }
}
Python
class Solution:
    def isNumber(self, s: str) -> bool:
        pattern = r'^[-+]?((\d+\.?|\.\d+|\d+\.\d+)([eE][-+]?\d+)?)$'
        return bool(re.match(pattern, s.strip()))

Complexity

  • ⏰ Time complexity: O(n), where n is the length of the input string. Checking a string against a regex will at most go through the length of the string.
  • 🧺 Space complexity: O(1) since the regex pattern is fixed in size and does not depend on the length of the input.