coverPiccoverPic

Leetcode 65 Valid Number

前言

Valid Number 要求判断一个由字母、数字、正负号、小数点组成的字符串是不是一个合法的数字,合法的数字就是:

  1. (+/-)整数或小数
  2. (+/-)整数或小数 + E或e + (+/-)整数

两种格式,例如:'1E3''-2e+5';不能这样子:'+E1''e''2E''+-1'

整数所有字符都是数字,小数有 3 种格式:

  1. 数字 + . + 数字
  2. 数字 + .
  3. . + 数字

也就是说,这些都是正确的数字:'0000''.0001''+114.E-514';这样子就不行:'.''+.''1.1.1''miao'

这个问题解法很明显,使用有限状态机,输入有:数字、符号、小数点、e、其他、结束,一共 6 种。状态可以根据字符串字符在 e 的前面还是后面,是整数还是小数设置,合法的状态转移如下所示:

初始状态DEFAULT
初始状态DEFAULT
符号(E前)
PRE_SIGN
符号(E前)PRE_SIGN符号(E前)PRE_SIGN
数字(E前)
PRE_INT
数字(E前)PRE_INT
小数点(E前)
PRE_POINT
小数点(E前)PRE_POINT
小数(E前)
PRE_DEC
小数(E前)PRE_DEC
e / E
E
e / EEe / EE
符号(E后)
POST_SIGN
符号(E后)POST_SIGN符号(E后)POST_SIGN
数字(E后)
POST_INT
数字(E后)POST_INT数字(E后)POST_INT
完成
SUCCESS
完成SUCCESS完成SUCCESS
第一个小数点PRE_FIRST_PONIT
第一个小数点PRE_FIRST_PONIT
符号 SIGN
符号 SIGN
数字 NUM
数字 NUM
输入字符
输入字符
小数点 POINT
小数点 POINT
e / E       E
e / E       E
结束 END
结束 END

时间复杂度 O(n)O(n)nn 是字符串长度,空间复杂度 O(1)O(1)

Code

ts
  1. const state = {
  2. PRE_SIGN: 0,
  3. PRE_INT: 1,
  4. PRE_POINT: 2,
  5. PRE_DEC: 3,
  6. E: 4,
  7. POST_SIGN: 5,
  8. POST_INT: 6,
  9. ERROR: 7,
  10. SUCCESS: 8,
  11. DEFAULT: 9,
  12. PRE_FIRST_POINT: 10
  13. }
  14. const input = {
  15. E: 0,
  16. NUM: 1,
  17. POINT: 2,
  18. SIGN: 3,
  19. ELSE: 4,
  20. END: 5
  21. }
  22. const transfer = [
  23. [state.ERROR, state.PRE_INT, state.PRE_FIRST_POINT, state.ERROR, state.ERROR, state.ERROR],
  24. [state.E, state.PRE_INT, state.PRE_POINT, state.ERROR, state.ERROR, state.SUCCESS],
  25. [state.E, state.PRE_DEC, state.ERROR, state.ERROR, state.ERROR, state.SUCCESS],
  26. [state.E, state.PRE_DEC, state.ERROR, state.ERROR, state.ERROR, state.SUCCESS],
  27. [state.ERROR, state.POST_INT, state.ERROR, state.POST_SIGN, state.ERROR, state.ERROR],
  28. [state.ERROR, state.POST_INT, state.ERROR, state.ERROR, state.ERROR, state.ERROR],
  29. [state.ERROR, state.POST_INT, state.ERROR, state.ERROR, state.ERROR, state.SUCCESS],
  30. undefined,
  31. undefined,
  32. [state.ERROR, state.PRE_INT, state.PRE_FIRST_POINT, state.PRE_SIGN, state.ERROR, state.ERROR],
  33. [state.ERROR, state.PRE_DEC, state.ERROR, state.ERROR, state.ERROR, state.ERROR]
  34. ]
  35. function isNumber(s: string): boolean {
  36. let currentState = state.DEFAULT
  37. const len = s.length
  38. for (let i = 0; i <= len; i++) {
  39. let inputType: number
  40. if (s[i] === 'e' || s[i] === 'E') {
  41. inputType = input.E
  42. } else if (s[i] >= '0' && s[i] <= '9') {
  43. inputType = input.NUM
  44. } else if (s[i] === '.') {
  45. inputType = input.POINT
  46. } else if (s[i] == '+' || s[i] === '-') {
  47. inputType = input.SIGN
  48. } else if (s[i] === undefined) {
  49. inputType = input.END
  50. } else {
  51. inputType = input.ELSE
  52. }
  53. currentState = transfer[currentState][inputType] as number
  54. if (currentState === state.ERROR || currentState === state.SUCCESS) {
  55. break
  56. }
  57. }
  58. return currentState === state.SUCCESS
  59. };
0 条评论未登录用户
Ctrl or + Enter 评论
© 2023-2025 LittleRangiferTarandus, All rights reserved.
🌸 Run