0468. 验证IP地址【中等】
1. 📝 题目描述
给定一个字符串 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 地址。
示例 1:
txt
输入:queryIP = "172.16.254.1"
输出:"IPv4"
解释:有效的 IPv4 地址,返回 "IPv4"1
2
3
2
3
示例 2:
txt
输入:queryIP = "2001:0db8:85a3:0:0:8A2E:0370:7334"
输出:"IPv6"
解释:有效的 IPv6 地址,返回 "IPv6"1
2
3
2
3
示例 3:
txt
输入:queryIP = "256.256.256.256"
输出:"Neither"
解释:既不是 IPv4 地址,又不是 IPv6 地址1
2
3
2
3
提示:
queryIP仅由英文字母,数字,字符'.'和':'组成。
2. 🎯 s.1 - 字符串模拟
c
bool isIPv4(char* s) {
int parts = 0;
char* p = s;
while (*p) {
if (!(*p >= '0' && *p <= '9')) return false;
int num = 0, len = 0;
while (*p >= '0' && *p <= '9') {
num = num * 10 + (*p - '0');
p++; len++;
}
if (len == 0 || len > 3 || num > 255) return false;
if (len > 1 && *(p - len) == '0') return false;
parts++;
if (*p == '.') p++;
else if (*p != '\0') return false;
}
return parts == 4 && *(p - 1) != '.';
}
bool isIPv6(char* s) {
int parts = 0;
char* p = s;
while (*p) {
int len = 0;
while ((*p >= '0' && *p <= '9') || (*p >= 'a' && *p <= 'f') || (*p >= 'A' && *p <= 'F')) {
p++; len++;
}
if (len == 0 || len > 4) return false;
parts++;
if (*p == ':') p++;
else if (*p != '\0') return false;
}
return parts == 8 && *(p - 1) != ':';
}
char* validIPAddress(char* queryIP) {
if (strchr(queryIP, '.') && isIPv4(queryIP)) return "IPv4";
if (strchr(queryIP, ':') && isIPv6(queryIP)) return "IPv6";
return "Neither";
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
js
/**
* @param {string} queryIP
* @return {string}
*/
var validIPAddress = function (queryIP) {
if (queryIP.includes('.')) {
const parts = queryIP.split('.')
if (parts.length !== 4) return 'Neither'
for (const p of parts) {
if (!p || p.length > 3 || (p.length > 1 && p[0] === '0')) return 'Neither'
const num = Number(p)
if (isNaN(num) || num < 0 || num > 255 || String(num) !== p)
return 'Neither'
}
return 'IPv4'
}
if (queryIP.includes(':')) {
const parts = queryIP.split(':')
if (parts.length !== 8) return 'Neither'
for (const p of parts) {
if (!p || p.length > 4) return 'Neither'
if (!/^[0-9a-fA-F]+$/.test(p)) return 'Neither'
}
return 'IPv6'
}
return 'Neither'
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
py
class Solution:
def validIPAddress(self, queryIP: str) -> str:
if '.' in queryIP:
parts = queryIP.split('.')
if len(parts) != 4:
return 'Neither'
for p in parts:
if not p or not p.isdigit() or (len(p) > 1 and p[0] == '0') or int(p) > 255:
return 'Neither'
return 'IPv4'
if ':' in queryIP:
parts = queryIP.split(':')
if len(parts) != 8:
return 'Neither'
for p in parts:
if not p or len(p) > 4:
return 'Neither'
try:
int(p, 16)
except ValueError:
return 'Neither'
return 'IPv6'
return 'Neither'1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
- 时间复杂度:
- 空间复杂度:
算法思路:
- 根据分隔符判断是 IPv4 还是 IPv6 候选
- IPv4:按
.分割为 4 部分,每部分为 0-255 的数字且无前导零 - IPv6:按
:分割为 8 部分,每部分为 1-4 位十六进制字符