Validate IP Address
这一类型的题,就是不断跟面试官做clarification和check你能考虑到的corner case。本身的实现并不难,难点在于交流及clarification。
这题的corner case有:
- IPv4的首位字符可能是".",当我们用Java的String类型的split()方法时,如果首位是分割符的时候,split出来的数组里的element的个数并不会增多,但是对于这个String本身来说,是不符合的。
- IPv4 最少一个字符,最多3个,且只能为数字,且数字 1 <= num <= 255。
- IPv6也要考虑第一个小点,split ":"时首位字符的问题
- IPv6每一段最少一个字符,最多4个
- IPv6里的字符,一定要在0 ~ 9或a ~ f或A ~ F之间的
public class Solution {
public String validIPAddress(String IP) {
if (IP.contains(".") && IP.contains(":")) {
return "Neither";
} else if (!IP.contains(".") && !IP.contains(":")) {
return "Neither";
}
if (IP.contains(".")) {
return checkIPv4(IP);
} else {
return checkIPv6(IP);
}
}
private String checkIPv4(String IP) {
if (IP.charAt(0) == '.' || IP.charAt(IP.length() - 1) == '.') {
return "Neither";
}
String[] strs = IP.split("\\.");
if (strs.length != 4) {
return "Neither";
}
for (int i = 0; i < 4; i++) {
String str = strs[i];
if (str.length() < 1 || str.length() > 3) {
return "Neither";
}
for (int j = 0; j < str.length(); j++) {
if (!Character.isDigit(str.charAt(j))) {
return "Neither";
}
}
if (str.charAt(0) == '0' && str.length() > 1) {
return "Neither";
}
int num = Integer.parseInt(str);
if (num < 0 || num > 255) {
return "Neither";
}
}
return "IPv4";
}
private String checkIPv6(String IP) {
if (IP.charAt(0) == ':' || IP.charAt(IP.length() - 1) == ':') {
return "Neither";
}
String[] strs = IP.split(":");
if (strs.length != 8) {
return "Neither";
}
for (int i = 0; i < 8; i++) {
String str = strs[i];
if (str.length() < 1 || str.length() > 4) {
return "Neither";
}
for (int j = 0; j < str.length(); j++) {
char c = str.charAt(j);
if (c >= '0' && c <= '9' || c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F') {
} else {
return "Neither";
}
}
}
return "IPv6";
}
}
String to Integer (atoi)
这题的corner case:
- meeting the first character which is sign
- meeting the character which is not a digit
- number overflow
public class Solution {
public int myAtoi(String str) {
if (str == null) {
return 0;
}
str = str.trim();
if (str.length() == 0) {
return 0;
}
int sign = 1, i = 0;
if (str.charAt(0) == '+' || str.charAt(0) == '-') {
if (str.charAt(0) == '-') {
sign = -1;
}
i++;
}
long num = 0;
while (i < str.length()) {
char c = str.charAt(i);
if (!Character.isDigit(c)) {
break;
}
num = num * 10 + c - '0';
if (num > Integer.MAX_VALUE) {
break;
}
i++;
}
if (num > Integer.MAX_VALUE) {
return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
}
return (int) num * sign;
}
}
Valid Number
Corner Case有:
- 首个字符是sign
- 遇到"."之前,已经遇到过了"."或者"e"
- 遇到e以后,不再遇到number了
- 遇到非首字符的sign时,他的之前的一个字符不是”e“
- 遇到上述情况以外的字符
public class Solution {
public boolean isNumber(String s) {
if (s == null) {
return false;
}
s = s.trim();
if (s.length() == 0) {
return false;
}
boolean num = false, dot = false, exp = false;
int i = 0;
if (s.charAt(i) == '+' || s.charAt(i) == '-') {
i++;
}
while (i < s.length()) {
char c = s.charAt(i);
if (Character.isDigit(c)) {
int j = i;
while (j < s.length() && Character.isDigit(s.charAt(j))) {
j++;
}
num = true;
i = j;
} else if (c == '.') {
if (dot || exp) {
return false;
}
dot = true;
i++;
} else if (c == 'e') {
if (!num || exp) {
return false;
}
exp = true;
num = false;
i++;
} else if (c == '+' || c == '-') {
if (s.charAt(i - 1) != 'e') {
return false;
}
i++;
} else {
return false;
}
}
return num;
}
}