有效数字(按顺序)可分为以下几个部分:
十进制或整数。
可选) a'e'或'e',后跟一个整数。
小数(按顺序)可分为以下几部分:
可选)符号字符('+'或'-')
以下格式之一:
至少一个数字,后跟一个点'.'
至少一个数字,后跟一个点'.'后跟至少一位数字。
一个点'.',后跟至少一位数字。
整数(按顺序)可以分为以下几个部分:
可选)符号字符('+'或'-')
至少一个数字。
下面列出了一些重要数字:
2", "0089", "-0.1", "+3.14", "4.", "-.9", "2e10", "-90e3", "3e+7", "+6e-1", "53.5e93", "-123.456e789"]
下面列出了一些无效数字:
abc", "1a", "1e", "e3", "99e2.5", "--6", "-+3", "95a54e53"]
给你一个字符串 s,如果 s 是有效数,则返回 true。
示例 1:输入:s ="0"
输出:true
示例 2:输入:s ="e"
输出:false
示例 3:输入:s ="."
输出:false
示例 4:输入:s =".1"
输出:true
提示:1 < = 秒length <= 20
s 仅包含英文字母(大写和小写)、数字 (0-9) 和加号'+'减去'-'或点'.' 。
我们可以直接遍历一次,边遍历边判断是否有效。
如果要遍历并确定它是否合法,则需要记录一些关键信息。 例如,当我穿越并遇到时,那么我其实需要知道一些信息,比如以前有没有完成。 如果已经出现,那么可以得出结论,该号码是非法的。
除了这样的信息,我们还需要注意其他信息。 具体来说,我们需要关注:
e e 前面有三个信息上面的数字。 我们可以使用三个变量,一个表示上次遇到它的时间(索引),-1 表示尚未遇到的位置。
其实这个问题的重点就是分析什么是非法的,那么什么不违法,那么它就是合法的。 之所以会这样,是因为法律上的太多了,我们没有办法一一判断,只能从违法的角度出发。 违法案件很多,如何归类是个问题,这也是为什么这个问题难缠不清的原因。
让我们分析一下非法场景。
点前面有一个 e 或点,例如 11.1 或 3e52e 前面有一个 e,就像 e12e 一样。 或者e前面没有数字,比如e123它前面有 e,或者前面有非法字符。 也就是说,除了 +-ee 之外还有一个数字。 在 ** 之外,我们可以使用三个变量:
最后一个点 .位置 最后 e 最后遇到 e e 最后 d 最后的数字 我们需要遍历字符串 s,并记得在迭代时更新三个变量。
如果我们遇到一个角色".",那么就不需要前面了".",并且不能有 e,否则就不合法。 如果遇到 e e,那么它前面就不可能有 e。 此外,前面还有数字。 如果遇到+-,要么是第一个字符,要么前面是e e,否则就不能合法,其他非数字字符也不合法,分析违法情况,用三个变量记录点、指数、数字的位置的最后一次出现,复制判断。
class solution: def isnumber(self, s: str) -bool: last_dot = last_e = last_d = -1 for i, c in enumerate(s): if c.isdigit():last_d = i elif c == '.': if last_dot != -1 or last_e != -1: return false last_dot = i elif c.lower() == 'e': if last_d == -1 or last_e != -1: return false last_e = i elif c == '+' or c == '-': if i == 0 or s[i-1].lower() == 'e': continue else: return false else: return false return s[-1].isdigit() or (s[-1] == '.' and last_d != -1)
复杂性分析设 n 为数组的长度。
时间复杂度:$o(n)$Space复杂度:$o(1)$
对于状态机,我们需要解决的是:
国家有哪些选择。
它类似于动态编程。对于这个问题,基础的状态是各种字符的类型。 即:
数字。 EE+-Primers 就是这四种类型。
没有必要区分ee和+-,因为两者在逻辑上没有区别。那么这四个就足够了。 这还不够。 这是因为标题的描述。 例如,标题说 e 后面不能跟小数。 好吧,对于.我们需要它有两种状态:e 在和 . 同样,对于 +- 符号,我们需要区分 e 之后的第一个和第一个(紧邻),因为第一位后面可以跟着不是紧跟在 e 后面的那个。 数字也是如此。 由于 e 不能跟着一点点,所以也需要类似的东西最后一个更容易被遗漏,我们需要一个只能跟着数字的数字状态,而不是其他任何东西。 例如,此时的 +2e+3,3 后面只能跟着一个数字,其他一切都是非法的。
对于这个问题:
图中的四个黄色部分是选择。 由于 +- 和 [1-9] 对我们的算法没有影响,因此它们不会单独提取,而是分组到一个类别中。 图中的虚线是状态。 不难看出,"."前后的状态选择不同。 所以除了:"+-", "[1-9]", "e/e", "."这些基本状态,我们还需要区分[1-9],e e为”之前或之后。 我从左到右编号,左边是 1,右边是 2,所以我们有 sign1、digit1、exp、d digit2 exp sign2 d。
请注意,这是 d,而不是 digit2。 由于 digit2 可以连接到 e,因此需要定义一个单独的状态。另外,由于点前后必须至少有一个数字,而数字的存在与否也会影响选择,因此我们还需要对此进行区分。 我在这里使用 dot1 表示前面有数字的点,用 dot2 表示前面有数字的点
至于如何蜕变,我就不一一分析了,咱们就看吧**。 虽然思路不难理解,但细节还是相当多的,大家自己写就知道了。
为了对状态机进行建模,如果我们知道有多少个状态,我们 xxx1 表示前一个 xxx,xxx2 表示下一个 xxx。 d 表示只能跟随数字。
语言支持:python3python3 代码:
类解: def isnumber(self, s: str) -bool: 任何状态机的核心都是对状态机进行建模,如下所示 状态 = ,"sign1": ,"sign2": ,"digit1": ,"digit2": ,"dot1":,前面没有数字"dot2":,前面有数字"exp": ,"d": def get(ch): if ch == ".": return "dot" elif ch in "+-": return "sign" elif ch in "ee": return "exp" elif ch.isdigit():return "digit" state = "start" for c in s: state = states[state].get(get(c)) if not state: return false return "end" in states[state]
复杂性分析设 n 为数组的长度。
时间复杂度:$o(n)$ 空间复杂度:虽然状态是用来存储状态的,但并不随着数量的增加而增加,而是一个固定值,所以空间复杂度为$o(1)$