题目要求
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/01f825b2f264d803fee3b9804ed46911.png)
思路:双指针
- 先根据分隔符判断是v4还是v6;
- 根据不同协议特征分别遍历判断,判断被分隔符分开的每一段是否合法,左指针指段首,右指针向后移动直到遇到分隔符;
- 最后判断分隔符数量。
Java
class Solution {
int n;
public String validIPAddress(String queryIP) {
n = queryIP.length();
if(queryIP.indexOf(".") >= 0 && ipv4(queryIP))
return "IPv4";
if(queryIP.indexOf(":") >= 0 && ipv6(queryIP))
return "IPv6";
return "Neither";
}
boolean ipv4(String ip) {
int splitCnt = 0;
for(int i = 0; i < n && splitCnt <= 3; ) {
int j = i, cur = 0;
while(j < n && ip.charAt(j) >= '0' && ip.charAt(j) <= '9' && cur <= 255)
cur = cur * 10 + (ip.charAt(j++) - '0');
if(i == j)
return false;
if((j - i > 1 && ip.charAt(i) == '0') || (cur > 255))
return false;
i = j + 1;
if(j == n)
continue;
if(ip.charAt(j) != '.')
return false;
splitCnt++;
}
return splitCnt == 3 && ip.charAt(0) != '.' && ip.charAt(n - 1) != '.';
}
boolean ipv6(String ip) {
int splitCnt = 0;
for(int i = 0; i < n && splitCnt <= 7; ) {
int j = i;
while(j < n && ((ip.charAt(j) >= 'a' && ip.charAt(j) <= 'f') || (ip.charAt(j) >= 'A' && ip.charAt(j) <= 'F') || (ip.charAt(j) >= '0' && ip.charAt(j) <= '9')))
j++;
if(i == j || j - i > 4)
return false;
i = j + 1;
if(j == n)
continue;
if(ip.charAt(j) != ':')
return false;
splitCnt++;
}
return splitCnt == 7 && ip.charAt(0) != ':' && ip.charAt(n - 1) != ':';
}
}
- 时间复杂度:
O
(
n
)
O(n)
O(n)
- 空间复杂度:
O
(
1
)
O(1)
O(1)
C++
class Solution {
int n;
public:
string validIPAddress(string queryIP) {
n = queryIP.size();
if(queryIP.find(".") != string::npos && ipv4(queryIP))
return "IPv4";
if(queryIP.find(":") != string::npos && ipv6(queryIP))
return "IPv6";
return "Neither";
}
bool ipv4(string ip) {
int splitCnt = 0;
for(int i = 0; i < n && splitCnt <= 3; ) {
int j = i, cur = 0;
while(j < n && ip[j] >= '0' && ip[j] <= '9' && cur <= 255)
cur = cur * 10 + (ip[j++] - '0');
if(i == j)
return false;
if((j - i > 1 && ip[i] == '0') || (cur > 255))
return false;
i = j + 1;
if(j == n)
continue;
if(ip[j] != '.')
return false;
splitCnt++;
}
return splitCnt == 3 && ip[0] != '.' && ip[n - 1] != '.';
}
bool ipv6(string ip) {
int splitCnt = 0;
for(int i = 0; i < n && splitCnt <= 7; ) {
int j = i;
while(j < n && ((ip[j] >= 'a' && ip[j] <= 'f') || (ip[j] >= 'A' && ip[j] <= 'F') || (ip[j] >= '0' && ip[j] <= '9')))
j++;
if(i == j || j - i > 4)
return false;
i = j + 1;
if(j == n)
continue;
if(ip[j] != ':')
return false;
splitCnt++;
}
return splitCnt == 7 && ip[0] != ':' && ip[n - 1] != ':';
}
};
- 时间复杂度:
O
(
n
)
O(n)
O(n)
- 空间复杂度:
O
(
1
)
O(1)
O(1)
Rust
impl Solution {
pub fn valid_ip_address(query_ip: String) -> String {
use std::net::{Ipv4Addr, Ipv6Addr};
query_ip
.parse::<Ipv4Addr>()
.map(|_| String::from("IPv4"))
.or(query_ip
.split(":")
.map(|x| if x.is_empty() { "g" } else {x})
.collect::<Vec<_>>()
.join(":")
.parse::<Ipv6Addr>()
.map(|_| String::from("IPv6")))
.unwrap_or_else(|_| String::from("Neither"))
}
}
- 时间复杂度:
O
(
n
)
O(n)
O(n)
- 空间复杂度:
O
(
1
)
O(1)
O(1)
总结
又是快乐的双指针,周末快乐~