89
89
90
90
<!-- 这里可写通用的实现逻辑 -->
91
91
92
- 遍历字符串:
92
+ ** 方法一:分类讨论 **
93
93
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$ 的长度。
97
113
98
114
<!-- tabs:start -->
99
115
104
120
``` python
105
121
class Solution :
106
122
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:
108
129
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" :
114
134
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 :
119
139
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 :
123
143
return False
124
- find_e = True
125
- find_num = False
144
+ e, digit = True , False
126
145
else :
127
146
return False
128
- return find_num
147
+ i += 1
148
+ return digit
129
149
```
130
150
131
151
### ** Java**
@@ -135,85 +155,169 @@ class Solution:
135
155
``` java
136
156
class Solution {
137
157
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) {
139
166
return false ;
140
167
}
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' ) {
148
174
return false ;
149
175
}
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 ) {
154
180
return false ;
155
181
}
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 ) {
159
185
return false ;
160
186
}
161
- findE = true ;
162
- findNum = false ; // 确保e之后也出现数
187
+ e = true ;
188
+ digit = false ;
163
189
} else {
164
190
return false ;
165
191
}
166
192
}
167
- return findNum ;
193
+ return digit ;
168
194
}
169
195
}
170
196
```
171
197
172
- ### ** JavaScript **
198
+ ### ** C++ **
173
199
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
+ }
181
239
};
182
240
```
183
241
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
+
184
282
### ** C#**
185
283
186
284
``` cs
187
285
public class Solution {
188
286
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 ) {
190
295
return false ;
191
296
}
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 ) {
195
299
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' ) {
197
301
return false ;
198
302
}
199
303
} else if (s [i ] >= '0' && s [i ] <= '9' ) {
200
- findNum = true ;
304
+ digit = true ;
201
305
} else if (s [i ] == '.' ) {
202
- if (findDot || findE ) {
306
+ if (dot || e ) {
203
307
return false ;
204
308
}
205
- findDot = true ;
309
+ dot = true ;
206
310
} else if (s [i ] == 'e' || s [i ] == 'E' ) {
207
- if (! findNum || findE ) {
311
+ if (! digit || e ) {
208
312
return false ;
209
313
}
210
- findE = true ;
211
- findNum = false ;
314
+ e = true ;
315
+ digit = false ;
212
316
} else {
213
317
return false ;
214
318
}
215
319
}
216
- return findNum ;
320
+ return digit ;
217
321
}
218
322
}
219
323
```
0 commit comments