LeetCode 468. 验证IP地址

题目描述

468. 验证 IP 地址

image-20250420050324314

思路分析

解法一:分段校验(推荐)

核心思路

  • 如果包含 .,按 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. 验证回文串 简单 双指针
本文作者:
本文链接: https://hgnulb.github.io/blog/2025/08020973
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!