From 576ba528fd95c2a0fa9e52f4b39619d8a296e066 Mon Sep 17 00:00:00 2001 From: ShusenTang Date: Mon, 3 Feb 2020 16:58:50 +0800 Subject: [PATCH] add 65 --- README.md | 1 + solutions/65. Valid Number.md | 65 +++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 solutions/65. Valid Number.md diff --git a/README.md b/README.md index 74d35ad..a0359c9 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ My LeetCode solutions with Chinese explanation. 我的LeetCode中文题解。 | 61 |[Rotate List](https://leetcode.com/problems/rotate-list/)|[C++](https://github.com/ShusenTang/LeetCode/blob/master/solutions/61.%20Rotate%20List.md)|Medium| | | 62 |[Unique Paths](https://leetcode.com/problems/unique-paths/)|[C++](https://github.com/ShusenTang/LeetCode/blob/master/solutions/62.%20Unique%20Paths.md)|Medium| | | 63 |[Unique Paths II](https://leetcode.com/problems/unique-paths-ii/)|[C++](https://github.com/ShusenTang/LeetCode/blob/master/solutions/63.%20Unique%20Paths%20II.md)|Medium| | +| 65 |[Valid Number](https://leetcode.com/problems/valid-number/)|[C++](solutions/65.%20Valid%20Number.md)|Hard| | | 66 |[Plus One](https://leetcode.com/problems/plus-one)|[C++](https://github.com/ShusenTang/LeetCode/blob/master/solutions/66.%20Plus%20One.md)|Easy| | | 67 |[Add Binary](https://leetcode.com/problems/add-binary)|[C++](https://github.com/ShusenTang/LeetCode/blob/master/solutions/67.%20Add%20Binary.md)|Easy| | | 69 |[Sqrt(x)](https://leetcode.com/problems/sqrtx)|[C++](https://github.com/ShusenTang/LeetCode/blob/master/solutions/69.%20Sqrt(x).md)|Easy| | diff --git a/solutions/65. Valid Number.md b/solutions/65. Valid Number.md new file mode 100644 index 0000000..f6bcfb7 --- /dev/null +++ b/solutions/65. Valid Number.md @@ -0,0 +1,65 @@ +# [65. Valid Number](https://leetcode.com/problems/valid-number/) + +# 思路 +验证给定的字符串是否表示一个合法的数值。 + +表示数值的字符串一定遵循模式`A.BeC`,其中A、B、C分别表示整数部分、小数部分和指数部分,e可用大写E替代。例如`-12.34e-56`,那么`A = -12, B = 34, C = -56`。 + +**其中A和C是可带符号的而B是无符号的。** + +为了判断给定的字符串是否能表示一个数值,我们只需从左到右尽可能多的扫描0-9的数位串得到A(可能以+-开头),如果紧接着跟了小数点“.”,那么需要继续尽可能多的扫描0-9数位串得到B,然后如果遇到了“e”或者“E”,再继续尽可能多的扫描0-9数位串得到C(可能以+-开头)。为此我们需要定义两个返回类型都为bool的函数`Scan_Signed(string &s)`和`Scan_Unsigned(string &s)`分别用于扫描AC和B,注意传入的是字符串的引用,我们会在函数结束前将`s`剩余未扫描的部分赋值给`s`。 + +需要注意根据测试样例我们可能需要去掉首尾的空格,另外`.2`和`2.`这种也是合法的。 + +只需要一次扫描因此时间复杂度为O(n),空间复杂度O(1)。 + +# C++ + +``` C++ +class Solution { +private: + bool Scan_Unsigned(string &s){ + // if(s.empty()) return false; + int i = 0; + while(i < s.size()){ + if(s[i] < '0' || s[i] > '9') break; + i++; + } + s = s.substr(i); // 将s剩余未扫描的部分赋值给s + return (i > 0); + } + + bool Scan_Signed(string &s){ + // if(s.empty()) return false; + if(s[0] == '+' || s[0] == '-') s = s.substr(1); + return Scan_Unsigned(s); + } + +public: + bool isNumber(string s) { + // if(s.empty()) return false; + + // 去掉首尾的空格 + int l = 0, r = s.size() - 1; + while(s[l] == ' ') l++; + while(l < r && s[r] == ' ') r--; + s = s.substr(l, r - l + 1); + + bool A = Scan_Signed(s); // 整数部分 + bool dot = (s[0] == '.'); // 小数点 + if(dot) s = s.substr(1); + bool B = (dot && Scan_Unsigned(s)); // 小数部分 + + if(!A && !B) return false; // 如果没有整数部分那么小数部分不能为空 + //if(A && dot && !B) return false; // "2."这种是合法的, 所以这里注释掉 + //if(!A && dot && B) return false; // ".2"这种也是合法的, 所以这里注释掉 + + if(s.empty()) return true; + + // 指数部分 + if(s[0] != 'e' && s[0] != 'E') return false; + s = s.substr(1); + return Scan_Signed(s) && s.empty(); + } +}; +``` \ No newline at end of file