LeetCode刷题笔记 – 65. 有效数字

这是我参与更文挑战的第3天,活动详情查看:更文挑战

65. 有效数字

题目

有效数字(按顺序)可以分成以下几个部分:

  • 一个 小数 或者 整数
  • (可选)一个 ‘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 。

示例

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

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

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

输入:s = ".1"
输出:true
复制代码

提示

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

解题思路分析

方式一:有限状态机

看到类似的题目,我们可以想到的就是利用有限状态机来进行状态的转移,关于状态机的介绍由于篇幅问题就不介绍了,有不清楚的小伙伴可以上网搜一下,网上很多大佬总结分享的都很详细。

首先,我们这里确定一下字符类型:
数字0—9、正负号+−、小数点.、幂符号eE

再对可能会遇到的情况进行一个状态的定义
按照字符串从左到右的顺序,定义以下 9 种状态, 以及后续遇到的正确状态

  1. 初始状态:正负号-1,数字-2,小数点-3
  2. 有正负号:数字-2,小数点-3
  3. 无正负号:数字-2,小数点-4,幂-5
  4. 无前缀的小数点:数字-4
  5. 有前缀的小数点/数字:数字-4,幂-5
  6. 幂:数字-7,正负号-6
  7. 幂符号后的正负号:数字-7
  8. 幂符号后的数字:数字-7
  9. 字母

image.png

由图可以看出,合法的结束状态有 2,4,7

代码

class Solution {
    public boolean isNumber(String s) {
        // 状态定义,第 9 种状态不符合条件,直接返回结果
        Map[] states = {
            new HashMap<>() {{ put('s', 1); put('d', 2); put('.', 3); }}, // 0
            new HashMap<>() {{ put('d', 2); put('.', 3); }}, // 1
            new HashMap<>() {{ put('d', 2); put('.', 4); put('e', 5); }}, // 2
            new HashMap<>() {{ put('d', 4); }}, // 3
            new HashMap<>() {{ put('d', 4); put('e', 5); }}, // 4
            new HashMap<>() {{ put('d', 7); put('s', 6); }}, // 5
            new HashMap<>() {{ put('d', 7); }}, // 6
            new HashMap<>() {{ put('d', 7); }} // 7
        };

        // 状态转移变量
        int p = 0;
        char t;
        
        // 遍历字符串
        for(char c : s.toCharArray()){
            if(c >= '0' && c <= '9'){
                t = 'd';
            } else if(c == '+' || c == '-'){
                t = 's';
            } else if(c == 'e' || c == 'E'){
                t = 'e';
            } else if(c == '.') {
                t = c;
            } else {
                return false;
            }
            // 判断当前字符是否为前状态所能遇上的正确后续
            if(!states[p].containsKey(t)) return false;
            // 更新状态
            p = (int)states[p].get(t);
        }
        return p == 2 || p == 4 || p == 7;
    }
}
复制代码

执行结果

image.png

复杂度分析

时间复杂度:O(n)
空间复杂度:O(1)

题目来源力扣:leetcode-cn.com/problems/va…

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享