Problem Statement in English

You’re given a string s representing a number. You need to determine if s is a valid number according to the following rules:

  • A valid number can be an integer, a decimal, or a number in scientific notation (e.g., “1e10”, “3.14E-2”).
  • The string may contain leading and trailing spaces, which should be ignored.
  • The string may contain a sign (’+’ or ‘-’) at the beginning of the number or after an ’e’ or ‘E’.

Return true if s is a valid number, and false otherwise.


Approach

This is an implementation problem.

We can split by the presence of ’e’ or ‘E’ to handle scientific notation. If ’e’ or ‘E’ is present, we split the string into two parts: the base and the exponent. The base can be a decimal or an integer, while the exponent must be an integer.

So we can create two helper functions: one to check if a string is a valid integer and another to check if a string is a valid decimal or integer.

And we’re done!


Solution in Python


class Solution:

    def isNumber(self, s: str) -> bool:
        # Handle exponent split
        if "e" in s or "E" in s:
            parts = s.replace("E", "e").split("e")
            if len(parts) != 2:
                return False
            return self.isDecimalOrInteger(
                parts[0]
            ) and self.isInteger(parts[1])

        return self.isDecimalOrInteger(s)

    def isInteger(self, s: str) -> bool:
        if not s:
            return False
        if s[0] in "+-":
            s = s[1:]
        return s.isdigit()

    def isDecimalOrInteger(self, s: str) -> bool:
        if not s:
            return False
        if s[0] in "+-":
            s = s[1:]
        if "." not in s:
            return s.isdigit()

        parts = s.split(".")
        if len(parts) != 2:
            return False

        # Must have digits, e.g., ".1", "1.", but NOT "."
        if not parts[0] and not parts[1]:
            return False

        # Parts can be empty (e.g. ".1" -> "" and "1"), but if non-empty, must be all digits
        return (not parts[0] or parts[0].isdigit()) and (
            not parts[1] or parts[1].isdigit()
        )

Complexity

  • Time: $O(n)$
    Since we are iterating through the string s once to check if it is a valid number, the time complexity is linear with respect to the length of the string.

  • Space: $O(1)$
    Since we are using a constant amount of space for variables and not using any additional data structures that grow with input size, the space complexity is constant.


And we are done.