题目描述
有效数字(按顺序)可以分成以下几个部分:
- 一个 小数 或者 整数
- (可选)一个
'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),加号'+'
,减号'-'
,或者点'.'
。
算法
(字符串处理) $O(n)$
- 找到字符串中第一次字符
e
的地方,记为e_pos
。 - 如果
e_pos
存在,则将字符分为两部分判断,e
之前的部分需要为一个整数或者浮点数。e
之后的部分需要为一个整数。 - 如果
e_pos
不存在,则整个字符串需要为一个整数或者浮点数。 - 判断整数或者浮点数时,需要满足一下几点
- 正负号仅能出现开头
- 字符串中需要至少有一个数字
- 判断浮点数时,
.
不能出现多次
时间复杂度
- 仅遍历常数次字符串,故时间复杂度为 $O(n)$。
空间复杂度
- 需要额外 $O(n)$ 的空间用于求子串,但可以通过记录下标的方式进行优化。
C++ 代码
class Solution {
private:
bool isPureNumber(const string &s, bool must_be_integer) {
if (s.empty()) return false;
int st = int(s[0] == '+' || s[0] == '-');
bool has_dot = false, has_digit = false;
for (int i = st; i < s.size(); i++) {
if (s[i] == '.') {
if (must_be_integer) return false;
if (has_dot) return false;
has_dot = true;
} else if (isdigit(s[i])) {
has_digit = true;
} else {
return false;
}
}
return has_digit;
}
public:
bool isNumber(string s) {
size_t e_pos = s.find('e');
size_t E_pos = s.find('E');
if (e_pos != string::npos)
return isPureNumber(s.substr(0, e_pos), false)
&& isPureNumber(s.substr(e_pos + 1), true);
if (E_pos != string::npos)
return isPureNumber(s.substr(0, E_pos), false)
&& isPureNumber(s.substr(E_pos + 1), true);
return isPureNumber(s, false);
}
};
这道题现在更新了,可以用
E
代替e
,并且不必strip
了感谢指出,题解已更新~