剑指 Offer 20. 表示数值的字符串

题目描述

请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。

  • 数值(按顺序)可以分成以下几个部分:

    1. 若干空格
    2. 一个小数或者整数
    3. (可选)一个 'e''E',后面跟着一个整数
    4. 若干空格
  • 小数(按顺序)可以分成以下几个部分:

    1. (可选)一个符号字符(’+’ 或 ‘-‘)
    2. 下述格式之一:

      1. 至少一位数字,后面跟着一个点 ‘.’
      2. 至少一位数字,后面跟着一个点 ‘.’ ,后面再跟着至少一位数字
      3. 一个点 ‘.’ ,后面跟着至少一位数字
  • 整数(按顺序)可以分成以下几个部分:

    1. (可选)一个符号字符(’+’ 或 ‘-‘)
    2. 至少一位数字

部分数值列举如下:

["+100""5e2""-123""3.1416""-1E-16""0123"]

部分非数值列举如下:

["12e""1a3.14""1.2.3""+-5""12e+5.4"]

示例 1:

输入:s = "0"
输出:true

示例 2:

输入:s = "e"
输出:false

示例 3:

输入:s = "."
输出:false

示例 4:

输入:s = "    .1  "
输出:true

提示:

1 <= s.length <= 20
s 仅含英文字母(大写和小写),数字(0-9),加号 '+' ,减号 '-' ,空格 ' ' 或者点 '.' 。

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解决方法

方法一:有限状态自动机

思路:通过对字符串的每一个元素从头开始遍历,若满足对应的转移条件,则跳转到对应的状态,否则提前返回False,若最终状态满足结束状态,则返回True,否则返回False。

状态有:

  • 0:字符串开始的空格
  • 1:幂符号前的’+’,’-‘
  • 2: 幂符号前的小数点前的数字
  • 3:小数点以及幂符号前小数点后的数字
    1. 当小数点前为空格时,小数点以及幂符号前小数点后的数字
  • 5:幂符号
  • 6:幂符号后的‘+’,‘-’
  • 7:幂符号后的数字
  • 8:字符串结束时的空格

根据题目可以写出状态转移规则,具体可见代码里states,其中states中第几个元素代表第一个状态,每个元素为一个字典,字典里key,value分别代表下一个状态的值以及下一个状态。

合法的结束状态:

  • 2, 3, 7, 8

符号定义:

  • d: 数字
  • s: ‘+’ or ‘-’
  • e: ‘e’ or ‘E’
  • c: ‘.’ or ‘ ‘
  • ?: 未知符号

代码:

class Solution:
    def isNumber(self, s: str) -> bool:
        states = [
            {' ': 0, 's': 1, 'd': 2, '.': 4},   # 0 字符串开始的空格
            {'d': 2, '.': 4},                   # 1 幂符号前的'+','-'
            {'d': 2, '.': 3, 'e': 5, ' ': 8},   # 2 幂符号前的小数点前的数字
            {'d': 3, 'e': 5, ' ': 8},           # 3 小数点以及幂符号前小数点后的数字
            {'d': 3},                           # 4 当小数点前为空格时,小数点以及幂符号前小数点后的数字
            {'s': 6, 'd': 7},                   # 5 幂符号
            {'d': 7},                           # 6 幂符号后的‘+’,‘-’ 
            {'d': 7, ' ': 8},                   # 7 幂符号后的数字
            {' ': 8},                           # 8 字符串结束时的空格
        ]
        p = 0                                   # 从状态0开始
        for char in s:
            if '0' <= char <= '9': t = 'd'
            elif char in 'eE': t = 'e' 
            elif char in '. ': t = char
            elif char in '+-': t = 's'
            else: t = '?'
            if t not in states[p]: return False
            p = states[p][t]
        return p in (2, 3, 7, 8)

复杂度分析:

  • 时间复杂度:O(n),  n为字符串长度
  • 空间复杂度:O(1)

发表评论