LeetCode 468. 验证IP地址
题目描述
思路分析
解法一:分段校验(推荐)
核心思路:
- 如果包含
.,按 IPv4 规则检查 4 段数字:每段 1~3 位,数值 0~255,且不能有前导零。- 如果包含
:,按 IPv6 规则检查 8 段十六进制:每段 1~4 位,字符需在 0-9/a-f/A-F。- 其它情况直接返回
Neither。
复杂度分析:
- 时间复杂度:O(n),其中 n 表示字符串长度。
- 空间复杂度:O(1),仅使用常数额外空间。
class Solution {
public String validIPAddress(String queryIP) {
if (queryIP.indexOf('.') >= 0) {
return isIPv4(queryIP) ? "IPv4" : "Neither";
}
if (queryIP.indexOf(':') >= 0) {
return isIPv6(queryIP) ? "IPv6" : "Neither";
}
return "Neither";
}
private boolean isIPv4(String s) {
String[] parts = s.split("\\.", -1);
if (parts.length != 4) {
return false;
}
for (String p : parts) {
if (p.length() == 0 || p.length() > 3) {
return false;
}
if (p.length() > 1 && p.charAt(0) == '0') {
return false;
}
int val = 0;
for (int i = 0; i < p.length(); i++) {
char c = p.charAt(i);
if (c < '0' || c > '9') {
return false;
}
val = val * 10 + (c - '0');
}
if (val > 255) {
return false;
}
}
return true;
}
private boolean isIPv6(String s) {
String[] parts = s.split(":", -1);
if (parts.length != 8) {
return false;
}
for (String p : parts) {
if (p.length() == 0 || p.length() > 4) {
return false;
}
for (int i = 0; i < p.length(); i++) {
char c = p.charAt(i);
boolean digit = c >= '0' && c <= '9';
boolean lower = c >= 'a' && c <= 'f';
boolean upper = c >= 'A' && c <= 'F';
if (!(digit || lower || upper)) {
return false;
}
}
}
return true;
}
}
func validIPAddress(queryIP string) string {
for i := 0; i < len(queryIP); i++ {
if queryIP[i] == '.' {
if isIPv4(queryIP) {
return "IPv4"
}
return "Neither"
}
if queryIP[i] == ':' {
if isIPv6(queryIP) {
return "IPv6"
}
return "Neither"
}
}
return "Neither"
}
func isIPv4(s string) bool {
parts := splitWithEmpty(s, '.')
if len(parts) != 4 {
return false
}
for _, p := range parts {
if len(p) == 0 || len(p) > 3 {
return false
}
if len(p) > 1 && p[0] == '0' {
return false
}
val := 0
for i := 0; i < len(p); i++ {
c := p[i]
if c < '0' || c > '9' {
return false
}
val = val*10 + int(c-'0')
}
if val > 255 {
return false
}
}
return true
}
func isIPv6(s string) bool {
parts := splitWithEmpty(s, ':')
if len(parts) != 8 {
return false
}
for _, p := range parts {
if len(p) == 0 || len(p) > 4 {
return false
}
for i := 0; i < len(p); i++ {
c := p[i]
digit := c >= '0' && c <= '9'
lower := c >= 'a' && c <= 'f'
upper := c >= 'A' && c <= 'F'
if !(digit || lower || upper) {
return false
}
}
}
return true
}
func splitWithEmpty(s string, sep byte) []string {
res := make([]string, 0)
start := 0
for i := 0; i <= len(s); i++ {
if i == len(s) || s[i] == sep {
res = append(res, s[start:i])
start = i + 1
}
}
return res
}
相似题目
| 题目 | 难度 | 考察点 |
|---|---|---|
| 93. 复原 IP 地址 | 中等 | 回溯、字符串 |
| 65. 有效数字 | 困难 | 字符串解析 |
| 8. 字符串转换整数 (atoi) | 中等 | 字符串处理 |
| 520. 检测大写字母 | 简单 | 字符串判断 |
| 125. 验证回文串 | 简单 | 双指针 |
本博客所有文章除特别声明外,均采用
CC BY-NC-SA 4.0
许可协议,转载请注明出处!
