leetcode65. 有效数字

98 篇文章 1 订阅
83 篇文章 1 订阅

在这里插入图片描述

思路一

作弊法:利用try…except机制,直接判断是否可以通过float()函数

class Solution:
    def isNumber(self, s: str) -> bool:
        try:
            float(s)
            return True
        except:
            return False

面试的时候这么写基本byebye

思路二

设置几个布尔值:dot_seen = Falsee_seen = Falsenum_seen = False,分别代表该类型的值是否已经出现过

利用s.strip()函数将s两边的空格去掉,然后遍历,根据当前元素的类型,将不是有效数字的情况列出,return False:

  1. 当前元素为数字,那么下一个元素是什么类型都可以,所以只要digit_seen变为True;
  2. 当前元素为e,如果之前已经出现过e,或者没有出现过数字,那么不是有效数字,False;
  3. 当前元素是小数点,如果之前已经出现过小数点或者e,那么不是有效数字,False;
  4. 当前元素是正负号,如果该元素不是首位,且前一个元素不是e,那么肯定不是有效数字,False。

代码

  class Solution:
        def isNumber(self, s: str) -> bool:     
            s = s.strip()
            dot_seen = False
            e_seen = False
            num_seen = False
            for i,a in enumerate(s):
                if a.isdigit():
                    num_seen = True
                elif a == '.':
                    if dot_seen or e_seen:
                        return False
                    dot_seen = True
                elif a == 'e':
                    if e_seen or not num_seen:
                        return False
                    e_seen = True
                    num_seen = False     #因为e之后必须再次判断是否出现数字,所以这里要把num_seen置为False
                elif a in '+-':
                    if i > 0 and s[i-1] != 'e':
                        return False
                else:
                    return False
            return num_seen

思路三

有限自动机法
我理解了一下,就是判断状态是否可以转移,最终是否能转移到合格的状态上,如图:
在这里插入图片描述

  1. 画出状态转移表,结构为states[n]存储n个状态;
  2. states[i]为一个HashTable,表示从此状态允许跳转到的状态;
  3. 主循环中遍历字符串,通过状态转移表判断结构是否成立:
    若中途遇到无法跳转的状态,直接返回False;
    若成功遍历完字符串,要判断结束状态是否在允许的结束状态内,本题为[3, 5, 8, 9]。

代码

class Solution:
    def isNumber(self, s: str) -> bool:
        state = [
            {},
            # 状态1,初始状态(扫描通过的空格)
            {"blank": 1, "sign": 2, "digit": 3, ".": 4},
            # 状态2,发现符号位(后面跟数字或者小数点)
            {"digit": 3, ".": 4},
            # 状态3,数字(一直循环到非数字)
            {"digit": 3, ".": 5, "e": 6, "blank": 9},
            # 状态4,小数点(后面只有紧接数字)
            {"digit": 5},
            # 状态5,小数点之后(后面只能为数字,e,或者以空格结束)
            {"digit": 5, "e": 6, "blank": 9},
            # 状态6,发现e(后面只能符号位, 和数字)
            {"sign": 7, "digit": 8},
            # 状态7,e之后(只能为数字)
            {"digit": 8},
            # 状态8,e之后的数字后面(只能为数字或者以空格结束)
            {"digit": 8, "blank": 9},
            # 状态9, 终止状态 (如果发现非空,就失败)
            {"blank": 9}
        ]

        cur_state = 1
        for i in s:
            if i.isdigit():
                i = 'num'
            elif i == '.':
                i = 'dot'
            elif i in '+-':
                i = 'sign'
            elif i == ' ':
                i = 'blank'
            elif i == 'e':
                i = 'e'
            if i not in state[cur_state]:
                return False
            cur_state = state[cur_state][i]
        return cur_state in [3,5,8,9]

参考

知乎上,九四干的leetcode刷题专栏

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值