Skip to content

Commit f8c648f

Browse files
committed
feat: add solutions to lcof problem: No.20
1 parent 2130b1a commit f8c648f

File tree

12 files changed

+322
-138
lines changed

12 files changed

+322
-138
lines changed

lcof/面试题20. 表示数值的字符串/README.md

Lines changed: 162 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,27 @@
8989

9090
<!-- 这里可写通用的实现逻辑 -->
9191

92-
遍历字符串:
92+
**方法一:分类讨论**
9393

94-
- 出现 `+`/`-` 时,位置必须是在第 0 位,或者 `e`/`E` 的后面一位
95-
- 出现 `.` 时,在此之前不能出现 `.` 或者 `e`/`E`
96-
- 出现 `e`/`E` 时,前面不能出现 `e`/`E`,并且必须出现过数字
94+
我们先去除字符串 $s$ 首尾的空格,此时 $i$ 和 $j$ 分别指向字符串 $s$ 的第一个非空格字符和最后一个非空格字符。
95+
96+
然后我们维护以下几个变量,其中:
97+
98+
- `digit`:表示是否出现过数字
99+
- `dot`:表示是否出现过点
100+
- `e`:表示是否出现过 `e` 或者 `E`
101+
102+
遍历 $s[i,..j]$ 范围内的每个字符,根据字符的类型进行分类讨论:
103+
104+
- 如果当前字符是 `+` 或者 `-`,那么该字符的前一个字符必须是 `e` 或者 `E`,或者空格,否则返回 `false`
105+
- 如果当前字符是数字,那么我们将 `digit` 置为 `true`
106+
- 如果当前字符是 `.`,那么该字符之前不能出现过 `.` 或者 `e`/`E`,否则返回 `false`,否则我们将 `dot` 置为 `true`
107+
- 如果当前字符是 `e` 或者 `E`,那么该字符之前不能出现过 `e`/`E`,并且必须出现过数字,否则返回 `false`,否则我们将 `e` 置为 `true`,并且将 `digit` 置为 `false`,表示 `e` 之后必须出现数字。
108+
- 如果当前字符是其它字符,那么返回 `false`
109+
110+
遍历结束后,我们返回 `digit`,即是否出现过数字。
111+
112+
时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为字符串 $s$ 的长度。
97113

98114
<!-- tabs:start -->
99115

@@ -104,28 +120,32 @@
104120
```python
105121
class Solution:
106122
def isNumber(self, s: str) -> bool:
107-
if not s or not s.strip():
123+
i, j = 0, len(s) - 1
124+
while i < j and s[i] == " ":
125+
i += 1
126+
while i <= j and s[j] == " ":
127+
j -= 1
128+
if i > j:
108129
return False
109-
s = s.strip()
110-
find_num = find_dot = find_e = False
111-
for i in range(len(s)):
112-
if s[i] == '+' or s[i] == '-':
113-
if i != 0 and s[i - 1] != 'e' and s[i - 1] != 'E':
130+
digit = dot = e = False
131+
while i <= j:
132+
if s[i] in "+-":
133+
if i and s[i - 1] not in " eE":
114134
return False
115-
elif s[i] >= '0' and s[i] <= '9':
116-
find_num = True
117-
elif s[i] == '.':
118-
if find_dot or find_e:
135+
elif s[i].isdigit():
136+
digit = True
137+
elif s[i] == ".":
138+
if dot or e:
119139
return False
120-
find_dot = True
121-
elif s[i] == 'e' or s[i] == 'E':
122-
if not find_num or find_e:
140+
dot = True
141+
elif s[i] in "eE":
142+
if not digit or e:
123143
return False
124-
find_e = True
125-
find_num = False
144+
e, digit = True, False
126145
else:
127146
return False
128-
return find_num
147+
i += 1
148+
return digit
129149
```
130150

131151
### **Java**
@@ -135,85 +155,169 @@ class Solution:
135155
```java
136156
class Solution {
137157
public boolean isNumber(String s) {
138-
if (s == null || s.trim().length() == 0) {
158+
int i = 0, j = s.length() - 1;
159+
while (i < j && s.charAt(i) == ' ') {
160+
++i;
161+
}
162+
while (i <= j && s.charAt(j) == ' ') {
163+
--j;
164+
}
165+
if (i > j) {
139166
return false;
140167
}
141-
char[] chars = s.trim().toCharArray();
142-
boolean findNum = false;
143-
boolean findE = false;
144-
boolean findDot = false;
145-
for (int i = 0, n = chars.length; i < n; ++i) {
146-
if (chars[i] == '+' || chars[i] == '-') {
147-
if (i != 0 && chars[i - 1] != 'e' && chars[i - 1] != 'E') {
168+
boolean digit = false;
169+
boolean dot = false;
170+
boolean e = false;
171+
for (; i <= j; ++i) {
172+
if (s.charAt(i) == '+' || s.charAt(i) == '-') {
173+
if (i > 0 && s.charAt(i - 1) != ' ' && s.charAt(i - 1) != 'e' && s.charAt(i - 1) != 'E') {
148174
return false;
149175
}
150-
} else if (chars[i] >= '0' && chars[i] <= '9') {
151-
findNum = true;
152-
} else if (chars[i] == '.') {
153-
if (findDot || findE) {
176+
} else if (Character.isDigit(s.charAt(i))) {
177+
digit = true;
178+
} else if (s.charAt(i) == '.') {
179+
if (dot || e) {
154180
return false;
155181
}
156-
findDot = true;
157-
} else if (chars[i] == 'e' || chars[i] == 'E') {
158-
if (findE || !findNum) {
182+
dot = true;
183+
} else if (s.charAt(i) == 'e' || s.charAt(i) == 'E') {
184+
if (!digit || e) {
159185
return false;
160186
}
161-
findE = true;
162-
findNum = false; // 确保e之后也出现数
187+
e = true;
188+
digit = false;
163189
} else {
164190
return false;
165191
}
166192
}
167-
return findNum;
193+
return digit;
168194
}
169195
}
170196
```
171197

172-
### **JavaScript**
198+
### **C++**
173199

174-
```js
175-
/**
176-
* @param {string} s
177-
* @return {boolean}
178-
*/
179-
var isNumber = function (s) {
180-
return s !== ' ' && !isNaN(+s);
200+
```cpp
201+
class Solution {
202+
public:
203+
bool isNumber(string s) {
204+
int i = 0, j = s.size() - 1;
205+
while (i < j && s[i] == ' ') {
206+
++i;
207+
}
208+
while (i <= j && s[j] == ' ') {
209+
--j;
210+
}
211+
if (i > j) {
212+
return false;
213+
}
214+
bool digit = false, dot = false, e = false;
215+
for (; i <= j; ++i) {
216+
if (s[i] == '+' || s[i] == '-') {
217+
if (i && s[i - 1] != ' ' && s[i - 1] != 'e' && s[i - 1] != 'E') {
218+
return false;
219+
}
220+
} else if (isdigit(s[i])) {
221+
digit = true;
222+
} else if (s[i] == '.') {
223+
if (dot || e) {
224+
return false;
225+
}
226+
dot = true;
227+
} else if (s[i] == 'e' || s[i] == 'E') {
228+
if (!digit || e) {
229+
return false;
230+
}
231+
e = true;
232+
digit = false;
233+
} else {
234+
return false;
235+
}
236+
}
237+
return digit;
238+
}
181239
};
182240
```
183241
242+
### **Go**
243+
244+
```go
245+
func isNumber(s string) bool {
246+
i, j := 0, len(s)-1
247+
for i < j && s[i] == ' ' {
248+
i++
249+
}
250+
for i <= j && s[j] == ' ' {
251+
j--
252+
}
253+
if i > j {
254+
return false
255+
}
256+
digit, dot, e := false, false, false
257+
for ; i <= j; i++ {
258+
if s[i] == '+' || s[i] == '-' {
259+
if i > 0 && s[i-1] != ' ' && s[i-1] != 'e' && s[i-1] != 'E' {
260+
return false
261+
}
262+
} else if s[i] >= '0' && s[i] <= '9' {
263+
digit = true
264+
} else if s[i] == '.' {
265+
if dot || e {
266+
return false
267+
}
268+
dot = true
269+
} else if s[i] == 'e' || s[i] == 'E' {
270+
if !digit || e {
271+
return false
272+
}
273+
digit, e = false, true
274+
} else {
275+
return false
276+
}
277+
}
278+
return digit
279+
}
280+
```
281+
184282
### **C#**
185283

186284
```cs
187285
public class Solution {
188286
public bool IsNumber(string s) {
189-
if (s == null || s.Trim() == null) {
287+
int i = 0, j = s.Length - 1;
288+
while (i < j && s[i] == ' ') {
289+
++i;
290+
}
291+
while (i <= j && s[j] == ' ') {
292+
--j;
293+
}
294+
if (i > j) {
190295
return false;
191296
}
192-
s = s.Trim();
193-
bool findNum = false, findDot = false, findE = false;
194-
for (int i = 0; i < s.Length; i++) {
297+
bool digit = false, dot = false, e = false;
298+
for (; i <= j; ++i) {
195299
if (s[i] == '+' || s[i] == '-') {
196-
if (i != 0 && s[i-1] != 'e' && s[i-1] != 'E') {
300+
if (i > 0 && s[i - 1] != ' ' && s[i - 1] != 'e' && s[i - 1] != 'E') {
197301
return false;
198302
}
199303
} else if (s[i] >= '0' && s[i] <= '9') {
200-
findNum = true;
304+
digit = true;
201305
} else if (s[i] == '.') {
202-
if (findDot || findE) {
306+
if (dot || e) {
203307
return false;
204308
}
205-
findDot = true;
309+
dot = true;
206310
} else if (s[i] == 'e' || s[i] == 'E') {
207-
if (!findNum || findE) {
311+
if (!digit || e) {
208312
return false;
209313
}
210-
findE = true;
211-
findNum = false;
314+
e = true;
315+
digit = false;
212316
} else {
213317
return false;
214318
}
215319
}
216-
return findNum;
320+
return digit;
217321
}
218322
}
219323
```
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
class Solution {
2+
public:
3+
bool isNumber(string s) {
4+
int i = 0, j = s.size() - 1;
5+
while (i < j && s[i] == ' ') {
6+
++i;
7+
}
8+
while (i <= j && s[j] == ' ') {
9+
--j;
10+
}
11+
if (i > j) {
12+
return false;
13+
}
14+
bool digit = false, dot = false, e = false;
15+
for (; i <= j; ++i) {
16+
if (s[i] == '+' || s[i] == '-') {
17+
if (i && s[i - 1] != ' ' && s[i - 1] != 'e' && s[i - 1] != 'E') {
18+
return false;
19+
}
20+
} else if (isdigit(s[i])) {
21+
digit = true;
22+
} else if (s[i] == '.') {
23+
if (dot || e) {
24+
return false;
25+
}
26+
dot = true;
27+
} else if (s[i] == 'e' || s[i] == 'E') {
28+
if (!digit || e) {
29+
return false;
30+
}
31+
e = true;
32+
digit = false;
33+
} else {
34+
return false;
35+
}
36+
}
37+
return digit;
38+
}
39+
};
Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,38 @@
11
public class Solution {
22
public bool IsNumber(string s) {
3-
if (s == null || s.Trim() == null) {
3+
int i = 0, j = s.Length - 1;
4+
while (i < j && s[i] == ' ') {
5+
++i;
6+
}
7+
while (i <= j && s[j] == ' ') {
8+
--j;
9+
}
10+
if (i > j) {
411
return false;
512
}
6-
s = s.Trim();
7-
bool findNum = false, findDot = false, findE = false;
8-
for (int i = 0; i < s.Length; i++) {
13+
bool digit = false, dot = false, e = false;
14+
for (; i <= j; ++i) {
915
if (s[i] == '+' || s[i] == '-') {
10-
if (i != 0 && s[i-1] != 'e' && s[i-1] != 'E') {
16+
if (i > 0 && s[i - 1] != ' ' && s[i - 1] != 'e' && s[i - 1] != 'E') {
1117
return false;
1218
}
1319
} else if (s[i] >= '0' && s[i] <= '9') {
14-
findNum = true;
20+
digit = true;
1521
} else if (s[i] == '.') {
16-
if (findDot || findE) {
22+
if (dot || e) {
1723
return false;
1824
}
19-
findDot = true;
25+
dot = true;
2026
} else if (s[i] == 'e' || s[i] == 'E') {
21-
if (!findNum || findE) {
27+
if (!digit || e) {
2228
return false;
2329
}
24-
findE = true;
25-
findNum = false;
30+
e = true;
31+
digit = false;
2632
} else {
2733
return false;
2834
}
2935
}
30-
return findNum;
36+
return digit;
3137
}
3238
}

0 commit comments

Comments
 (0)