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

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


题目描述

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

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

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

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

(可选)一个符号字符('+' 或 '-') 下述格式之一: 至少一位数字,后面跟着一个点 '.' 至少一位数字,后面跟着一个点 '.' ,后面再跟着至少一位数字 一个点 '.' ,后面跟着至少一位数字 整数(按顺序)可以分成以下几个部分:

(可选)一个符号字符('+' 或 '-') 至少一位数字 部分数值列举如下:

["+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),加号 '+' ,减号 '-' ,空格 ' ' 或者点 '.' 。

解题思路

法1

方法1:模拟\

  1. 特殊规则:
  • e后必须跟数字
  • 点前必须跟数字
  • 只能有一个点
  1. 去掉空格 首先使用 strings.TrimSpace 函数去掉字符串两端的空格,然后遍历字符串中的每一个字符,根据题目所述的规则来判断该字符是否属于数值表示的一部分。:

  2. 模拟数字判断 一个小数或者整数:遍历字符串中的每一个字符,如果该字符是数字,则说明字符串表示了小数或者整数的一部分;否则如果该字符是符号字符(+ 或 -),则需要判断该符号字符是否出现在字符串的第一个位置,或者出现在字符 e 或 E 的后面,如果都不是,则说明字符串不是合法的数值表示。 (可选)一个 'e' 或 'E',后面跟着一个整数:如果字符串中存在 e 或 E,则说明该字符串表示了指数形式的数值,需要特别处理。具体来说,如果字符串中没有数字或者已经存在了 e 或 E,或者 e 或 E 出现在字符串的最后一个位置,则说明字符串不是合法的数值表示;否则可以继续判断后面的整数部分是否合法。 若干空格:同样使用 strings.TrimSpace 函数去掉字符串两端的空格即可。

  • 小数:小数表示的规则比较复杂,需要分多种情况讨论。具体来说,如果字符串中已经存在了 e 或 E,则说明小数部分已经结束,不需要再继续判断;否则需要分别考虑以下情况: 第一个字符是符号字符(+ 或 -):如果符号字符出现在第一个位置,则说明该小数是正数或负数;否则如果符号字符出现在小数的中间,则说明该小数不是合法的数值表示。 小数点后面至少有一位数字:如果小数点后面没有数字,则说明该小数不是合法的数值表示。

  • 整数:整数表示的规则比较简单

  1. 符号(+/-)可选
  2. 数字

总体来说就是小数与幂难求

  • 时间复杂度(O(n))
  • 空间复杂度(O(n))

执行结果

法1
func isNumber(s string) bool {
    s = strings.TrimSpace(s)
    if s == "" {
        return false
    }
    hasNum := false//数字匹配规则
    hasDot := false//点匹配规则
    hasE := false//e匹配规则
    for i, c := range s {
        if c >= '0' && c <= '9' {
            hasNum = true
        } else if c == '+' || c == '-' {
            if i != 0 && s[i-1] != 'e' && s[i-1] != 'E' {
                return false
            }
        } else if c == 'e' || c == 'E' {
            if hasE || !hasNum || i == len(s)-1 {
                return false
            }
            hasE = true
        } else if c == '.' {
            if hasDot || hasE {
                return false
            }
            hasDot = true
        } else {
            return false
        }
    }
    if hasE && (!hasNum || s[len(s)-1] == 'e' || s[len(s)-1] == 'E') {
        return false
    }
    return hasNum
}

执行结果: 通过 显示详情 查看示例代码 添加备注

执行用时: 0 ms , 在所有 Go 提交中击败了 100.00% 的用户 内存消耗: 2 MB , 在所有 Go 提交中击败了 79.17% 的用户 通过测试用例: 1480 / 1480 炫耀一下:

法2

法3

本文由 mdnice 多平台发布

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值