原题链接
题目描述
给定一个字符串
queryIP。如果是有效的IPv4地址,返回"IPv4";如果是有效的IPv6地址,返回"IPv6";如果不是上述类型的IP地址,返回"Neither"。有效的
IPv4地址 是“x1.x2.x3.x4”形式的IP地址。 其中0 <= xi <= 255且xi不能包含 前导零。例如:“192.168.1.1”、“192.168.1.0”为有效IPv4地址,“192.168.01.1”为无效IPv4地址;“192.168.1.00”、“192.168@1.1”为无效IPv4地址。一个有效的IPv6地址 是一个格式为
“x1:x2:x3:x4:x5:x6:x7:x8”的IP地址,其中:
1 <= xi.length <= 4xi 是一个 十六进制字符串 ,可以包含数字、小写英文字母( 'a' 到 'f' )和 大写英文字母( 'A' 到 'F' )。- 在 xi 中允许前导零。
- 例如
"2001:0db8:85a3:0000:0000:8a2e:0370:7334"和"2001:db8:85a3:0:0:8A2E:0370:7334"是有效的 IPv6 地址,- 而
"2001:0db8:85a3::8A2E:037j:7334"和"02001:0db8:85a3:0000:0000:8a2e:0370:7334"是无效的 IPv6 地址。
输入示例
思路
整体:
- 如果字符串长度大于 32 + 7 = 39; 则不可能是 IPv4 也不可能是 IPv6;
- (优化) IPv4 的最小长度需要为 7 (
0.0.0.0); 字符串长度小于 7 也符合任意格式
验证是否为 IPv4:
- 按照
.分割需要长度为 4 - 对于每一段; 如果该段长度大于 1 则不能包含前导 0
- 每一段需要满足正则表达式
\\d+; 不能包含非数字的字符 - 借助
Integer.parseInt转化成整数后需要满足范围[0 ~ 255]
验证是否为 IPv6:
- 将所有字符转化为小写字符,统一方便处理
- 按照 : 分割需要满足长度为 8
- 分割后每一段需要满足正则表达式
^[0-9a-f]{1,4}$- 数字可包含 0 ~ 9
- 字符可以包含小写 a-f (由于统一 toLowCase 处理,不考虑大写)
- 并且每一段需要满足长度 1 ~ 4
(优化) 借助正则表达式
对于频繁使用的情况,可以考虑将正则表达式编译为 Pattern 对象,然后复用该对象进行匹配,这样可以提高正则表达式匹配的效率。
// 提前编译验证 IPv4 的正则表达式
private Pattern IPV4_SEGMENT_PATTERN = Pattern.compile("\\d+");
// 提前编译验证 IPv6 的正则表达式
private Pattern IPV6_SEGMENT_PATTERN = Pattern.compile("^[0-9a-f]{1,4}$");
代码
import java.util.regex.Pattern;
class Solution {
// 提前编译验证 IPv4 的正则表达式
private Pattern IPV4_SEGMENT_PATTERN = Pattern.compile("\\d+");
// 提前编译验证 IPv6 的正则表达式
private Pattern IPV6_SEGMENT_PATTERN = Pattern.compile("^[0-9a-f]{1,4}$");
public String validIPAddress(String queryIP) {
// 默认答案
String ans = "Neither";
// 长度大于 39 则不可能是 IPv4 或者 IPv6
if (queryIP.length() > 39 || queryIP.length() < 7) {
return ans;
}
// 判断是否是 IPv4
if (isIPv4(queryIP)) {
ans = "IPv4";
}
// 判断是否是 IPv6
if (isIPv6(queryIP)) {
ans = "IPv6";
}
return ans;
}
private boolean isIPv6(String queryIP) {
queryIP = queryIP.toLowerCase();
String[] str = queryIP.split(":", -1);
// 按照 : 分割后长度为 8
if (str.length != 8) {
return false;
}
for (String s : str) {
// 包含有非数字和字母的字符或者字母不在[a~f]范围内
if (!IPV6_SEGMENT_PATTERN.matcher(s).matches()) {
return false;
}
}
return true;
}
private boolean isIPv4(String queryIP) {
String[] str = queryIP.split("\\.", -1);
// 分割后长度为 4
if (str.length != 4)
return false;
for (String s : str) {
// 不能含有前导0
if (s.length() > 1 && s.charAt(0) == '0') {
return false;
}
// 包含有非数字字符
if (!IPV4_SEGMENT_PATTERN.matcher(s).matches()) {
return false;
}
// 不满足区间 0 ~ 255
int num = Integer.parseInt(s);
if (num < 0 || num > 255) {
return false;
}
}
return true;
}
}
结果分析
- 时间复杂度:
O(N) - 空间复杂度:
O(N)
笔试 / 面试记录
- 中金国际 - 笔试题 ✔ [输入方式: ACM 模式
无输入输出]