Skip to content

Commit f80fd65

Browse files
author
王鹏
committed
feat(HARD): add _65_isNumber
1 parent 6a43866 commit f80fd65

File tree

1 file changed

+167
-0
lines changed

1 file changed

+167
-0
lines changed
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
package pp.arithmetic.leetcode;
2+
3+
/**
4+
* Created by wangpeng on 2019-10-18.
5+
* 65. 有效数字
6+
* <p>
7+
* 验证给定的字符串是否可以解释为十进制数字。
8+
* <p>
9+
* 例如:
10+
* <p>
11+
* "0" => true
12+
* " 0.1 " => true
13+
* "abc" => false
14+
* "1 a" => false
15+
* "2e10" => true
16+
* " -90e3   " => true
17+
* " 1e" => false
18+
* "e3" => false
19+
* " 6e-1" => true
20+
* " 99e2.5 " => false
21+
* "53.5e93" => true
22+
* " --6 " => false
23+
* "-+3" => false
24+
* "95a54e53" => false
25+
* <p>
26+
* 说明: 我们有意将问题陈述地比较模糊。在实现代码之前,你应当事先思考所有可能的情况。这里给出一份可能存在于有效十进制数字中的字符列表:
27+
* <p>
28+
* 数字 0-9
29+
* 指数 - "e"
30+
* 正/负号 - "+"/"-"
31+
* 小数点 - "."
32+
* 当然,在输入中,这些字符的上下文也很重要。
33+
* <p>
34+
* 更新于 2015-02-10:
35+
* C++函数的形式已经更新了。如果你仍然看见你的函数接收 const char * 类型的参数,请点击重载按钮重置你的代码
36+
* <p>
37+
* 来源:力扣(LeetCode)
38+
* 链接:https://leetcode-cn.com/problems/valid-number
39+
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
40+
*/
41+
public class _65_isNumber {
42+
43+
public static void main(String[] args) {
44+
_65_isNumber isNumber = new _65_isNumber();
45+
/**
46+
*
47+
* "0" => true
48+
* " 0.1 " => true
49+
* "abc" => false
50+
* "1 a" => false
51+
* "2e10" => true
52+
* " -90e3   " => true
53+
* " 1e" => false
54+
* "e3" => false
55+
* " 6e-1" => true
56+
* " 99e2.5 " => false
57+
* "53.5e93" => true
58+
* " --6 " => false
59+
* "-+3" => false
60+
* "95a54e53" => false
61+
*/
62+
System.out.println(isNumber.isNumber("+.8")); //true
63+
System.out.println(isNumber.isNumber("-e58 ")); //false
64+
System.out.println(isNumber.isNumber("3.")); //true
65+
System.out.println(isNumber.isNumber("01")); //true
66+
System.out.println(isNumber.isNumber(".1")); //true
67+
System.out.println(isNumber.isNumber("0")); //true
68+
System.out.println(isNumber.isNumber("0.1")); //true
69+
System.out.println(isNumber.isNumber("abc")); //false
70+
System.out.println(isNumber.isNumber("1 a")); //false
71+
System.out.println(isNumber.isNumber("2e10")); //true
72+
System.out.println(isNumber.isNumber("-90e3")); //true
73+
System.out.println(isNumber.isNumber(" 1e")); //false
74+
System.out.println(isNumber.isNumber("e3")); //false
75+
System.out.println(isNumber.isNumber(" 6e-1")); //true
76+
System.out.println(isNumber.isNumber(" 99e2.5"));//false
77+
System.out.println(isNumber.isNumber("53.5e93"));//true
78+
System.out.println(isNumber.isNumber(" --6")); //false
79+
System.out.println(isNumber.isNumber("-+3")); //false
80+
System.out.println(isNumber.isNumber("95a54e53"));//false
81+
}
82+
83+
/**
84+
* 解题思路:
85+
* 本题最大的难点在于各种情况互相依赖,后面想了想,每种情况只关注自己该放的位置就可以了
86+
* caseTest有1400多个,情况比较多,导致提交多次,比较全的caseTest参考上面链接
87+
* 1、输入左右可能有空格,先去除左右空格
88+
* 2、对于length==1的情况,直接判断是否是0-9
89+
* 3、添加几个计数器减少循环次数(e的个数、小数点的个数、+,-的个数)
90+
* 4、开始循环
91+
* 5、对于数字:直接continue,01都是满足条件的
92+
* 6、对于+\-:最多出现2次(最前面和e的后面),出现直接可以跟数字和.
93+
* 7、对于e:最多出现1次,出现的位置不能在头和尾
94+
* 8、对于.:最多1个点,如果之前出现过 e ,则后续不允许有点,出现以后其前后至少有一个数字 .1
95+
*
96+
*
97+
* 执行用时 :3 ms, 在所有 java 提交中击败了94.47%的用户
98+
* 内存消耗 :36 MB, 在所有 java 提交中击败了89.15%的用户
99+
* @param s
100+
* @return
101+
*/
102+
public boolean isNumber(String s) {
103+
//1、输入左右可能有空格,先去除左右空格
104+
s = s.trim();
105+
//2、对于length==1的情况,直接判断是否是0-9
106+
if (s.length() == 0) return false;
107+
if (s.length() == 1) {
108+
return isNumber(s.charAt(0));
109+
}
110+
111+
//3、添加几个计数器减少循环次数
112+
//e的个数
113+
int eCount = 0;
114+
//小数点的个数
115+
int dCount = 0;
116+
//+,-的个数
117+
int oCount = 0;
118+
119+
//4
120+
for (int i = 0; i < s.length(); i++) {
121+
char c = s.charAt(i);
122+
if (isNumber(c)) {
123+
//5:直接continue,01都是满足条件的
124+
} else if (c == '-' || c == '+') {
125+
//6:最多出现2次(最前面和e的后面),出现直接可以跟数字和.
126+
if (oCount > 1) return false;
127+
//对满足条件的取反
128+
if (!((i == 0 && (isNumber(s.charAt(i + 1)) || s.charAt(i + 1) == '.')) || (i > 0 && i < s.length() - 1 && s.charAt(i - 1) == 'e'))) {
129+
return false;
130+
}
131+
oCount++;
132+
} else if (c == 'e') {
133+
//7、对于e:最多出现1次,出现的位置不能在头和尾
134+
if (eCount > 0) return false;
135+
if (!(i > 0 && i < s.length() - 1)) {
136+
return false;
137+
}
138+
eCount++;
139+
} else if (c == '.') {
140+
//8、对于.:最多1个点,如果之前出现过 e ,则后续不允许有点,出现以后其前后至少有一个数字 .1
141+
if (dCount > 0 || eCount > 0) return false;
142+
//点前后必须有一个数字
143+
if (i == 0) {
144+
if (!isNumber(s.charAt(i + 1)))
145+
return false;
146+
} else if (i == s.length() - 1) {
147+
if (!isNumber(s.charAt(i - 1)))
148+
return false;
149+
} else {
150+
if (!isNumber(s.charAt(i + 1)) && !isNumber(s.charAt(i - 1))) {
151+
return false;
152+
}
153+
}
154+
dCount++;
155+
} else {
156+
return false;
157+
}
158+
}
159+
160+
return true;
161+
}
162+
163+
private boolean isNumber(char c) {
164+
return c >= '0' && c <= '9';
165+
}
166+
167+
}

0 commit comments

Comments
 (0)