题目
给定一个字符串 IP 。
- 如果是有效的 IPv4 地址,返回
_"IPv4"_
; - 如果是有效的 IPv6 地址,返回
_"IPv6"_
; - 如果不是上述类型的 IP 地址,返回
_"Neither"_
。
示例 1:
输入:queryIP = “172.16.254.1” 输出:“IPv4” 解释:有效的 IPv4 地址,返回 “IPv4”
示例 2:
输入:queryIP = “2001:0db8:85a3:0:0:8A2E:0370:7334” 输出:“IPv6” 解释:有效的 IPv6 地址,返回 “IPv6”
解题思路:字符串判断
有效的 IPv4 地址 是 “x1.x2.x3.x4”
形式的IP地址。
- 其中
且
不能包含 前导零。
有效的IPv6地址 是一个格式为“x1:x2:x3:x4:x5:x6:x7:x8”
形式的IP地址。
- 在
中允许前导零。
是一个 十六进制字符串 ,可以包含数字、大小写英文字母(
'A'
到'F'
注意一种特殊情况:"2001:0db8:85a3:0:0:8A2E:0370:7334**:**"
当末尾是:号时,通过split(":")
分割出来的依旧是 8 组,因此需要加上一个判断,排除这种情况。
复杂度分析
时间复杂度: ,其中
是数组
的长度。
空间复杂度: ,其中
是数组
的长度。
我的代码
public class Solution {
public String solve (String IP) {
// write code here
// 判断是否是 IPv6
if(IP.contains(":")){
// 尾巴判断一下最后一个字符是否是":"
if(IP.charAt(IP.length()-1)==':')return "Neither";
// IPv6 地址由8组16进制的数字来表示,每组表示 16 比特。这些组数字通过 (":")分割
String[]Ipv6s=IP.split(":");
if(Ipv6s.length!=8)return "Neither";
// 可以 0 开头的数字,字母可以使用大写,也可以是小写
for(String ipv6:Ipv6s){
// 长度要求在[1,4]之间,可以有前导0
if(ipv6.length()>4||ipv6.length()<1) return "Neither";
// 16进制的数字来表示
for(int i=0;i<ipv6.length();i++){
// 判断是否是16进制数,是就分号;什么也不做
if(('A'<=ipv6.charAt(i)&&ipv6.charAt(i)<='F')||
('a'<=ipv6.charAt(i)&&ipv6.charAt(i)<='f')||
('0'<=ipv6.charAt(i)&&ipv6.charAt(i)<='9')
);// 分号结束,无执行语句
else return "Neither";
}
}
return "IPv6";
}else{ // IPv4
// IPv4 每个地址包含4个十进制数,其范围为 0 - 255, 用(".")分割
String[]Ipv4s=IP.split("\\.");
// 判断是否是4组数字
if(Ipv4s.length!=4)return "Neither";
for(String ipv4:Ipv4s){
// IPv4 地址内的数不会以 0 开头
if(ipv4==null||ipv4.length()==0||ipv4.charAt(0)=='0')
return "Neither";
// 判断是否是数字
for(int i=0;i<ipv4.length();i++){
if('0'<=ipv4.charAt(i)&&ipv4.charAt(i)<='9'); // 分号结束,无执行语句
else return "Neither";
}
// 判断是否值范围在[0,255]
int Ipv4num=Integer.parseInt(ipv4);
if(!(0<=Ipv4num&&Ipv4num<=255)) return "Neither";
}
return "IPv4";
}
}
}