LeetCode 468 验证 IP 地址


文章目录

摘要

《验证 IP 地址》是一道非常工程化的题

它不像很多算法题那样考复杂技巧,而是更像我们在写后台接口、网关校验、日志解析时,经常会遇到的那种"脏数据判断"问题。

这道题的核心不在算法,而在于三点:

  • 规则是否吃透
  • 边界是否考虑完整
  • 代码是否足够清晰、可维护

如果你平时写过参数校验、输入校验,这道题会让你有一种"这不就是我每天在干的事吗"的熟悉感。

描述

题目给你一个字符串 queryIP,要求判断它属于哪一种类型:

  • 合法的 IPv4 → 返回 "IPv4"
  • 合法的 IPv6 → 返回 "IPv6"
  • 两者都不是 → 返回 "Neither"

IPv4 的规则可以总结成一句话

复制代码
x1.x2.x3.x4
  • 必须正好 4 段
  • 每段是 0~255 的十进制数字
  • 不能有前导零
  • 只能是数字,不能夹杂奇怪字符

IPv6 的规则则是

复制代码
x1:x2:x3:x4:x5:x6:x7:x8
  • 必须正好 8 段
  • 每段 1~4 位
  • 只能是十六进制字符(0-9, a-f, A-F)
  • 允许前导零
  • 不支持 :: 这种缩写(这是本题特别容易踩的坑)

题解答案

整体解法非常直接,也非常"工程化":

  1. 先看分隔符

    • 包含 . → 尝试按 IPv4 规则解析
    • 包含 : → 尝试按 IPv6 规则解析
  2. 严格按规则逐段校验

  3. 任何一条不满足,直接判 Neither

核心原则只有一个:
宁可判错为非法,也不能放过一个非法输入。

题解代码分析

下面是完整的 Swift 实现,结构清晰,逻辑拆分明确,可以直接运行。

swift 复制代码
class Solution {
    func validIPAddress(_ queryIP: String) -> String {
        if queryIP.contains(".") {
            return isValidIPv4(queryIP) ? "IPv4" : "Neither"
        }

        if queryIP.contains(":") {
            return isValidIPv6(queryIP) ? "IPv6" : "Neither"
        }

        return "Neither"
    }

    private func isValidIPv4(_ ip: String) -> Bool {
        let parts = ip.split(separator: ".", omittingEmptySubsequences: false)
        if parts.count != 4 { return false }

        for part in parts {
            // 不能为空
            if part.isEmpty { return false }

            // 不能有前导零
            if part.count > 1 && part.first == "0" {
                return false
            }

            // 必须全是数字
            guard let num = Int(part), num >= 0 && num <= 255 else {
                return false
            }
        }

        return true
    }

    private func isValidIPv6(_ ip: String) -> Bool {
        let parts = ip.split(separator: ":", omittingEmptySubsequences: false)
        if parts.count != 8 { return false }

        for part in parts {
            // 长度 1~4
            if part.isEmpty || part.count > 4 {
                return false
            }

            for ch in part {
                if !ch.isHexDigit {
                    return false
                }
            }
        }

        return true
    }
}

IPv4 校验逻辑拆解

swift 复制代码
let parts = ip.split(separator: ".", omittingEmptySubsequences: false)

这里非常关键的一点是:
不能省略空字符串

否则像下面这种:

复制代码
"192..168.1"

会被错误拆成 3 段。

swift 复制代码
if part.count > 1 && part.first == "0"

这一步是专门防:

  • "01"
  • "001"

这是 IPv4 非常典型的坑点。

IPv6 校验逻辑拆解

IPv6 这边反而规则更"干净":

  • 段数必须 8
  • 每段最多 4 位
  • 每个字符必须是十六进制

Swift 的这个 API 在这里非常好用:

swift 复制代码
ch.isHexDigit

可读性和安全性都比手写判断强。

示例测试及结果

示例 1

swift 复制代码
let solution = Solution()
print(solution.validIPAddress("172.16.254.1"))

输出:

复制代码
IPv4

原因很简单:

4 段、范围合法、无前导零。

示例 2

swift 复制代码
print(solution.validIPAddress("2001:0db8:85a3:0:0:8A2E:0370:7334"))

输出:

复制代码
IPv6

大小写混用、前导零,全都允许。

示例 3

swift 复制代码
print(solution.validIPAddress("256.256.256.256"))

输出:

复制代码
Neither

单段数值超出 255,直接判非法。

时间复杂度

  • IPv4:最多检查 4 段
  • IPv6:最多检查 8 段,每段 4 个字符

整体时间复杂度:

复制代码
O(n)

其中 n 是字符串长度,实际上非常小。

空间复杂度

只使用了拆分后的数组和少量变量:

复制代码
O(1)

总结

《验证 IP 地址》这道题,非常不像"刷题",但非常像"真实工作"

它真正考察的是:

  • 你能不能严格遵守规则
  • 你会不会遗漏边界
  • 你的代码是否清晰、可维护、可扩展
相关推荐
TracyCoder12342 分钟前
LeetCode Hot100(13/100)——238. 除了自身以外数组的乘积
算法·leetcode
CoderCodingNo43 分钟前
【GESP】C++五级练习题 luogu-P3353 在你窗外闪耀的星星
开发语言·c++·算法
Anastasiozzzz1 小时前
LeetCode Hot100 215. 数组中的第K个最大元素
数据结构·算法·leetcode
让我上个超影吧1 小时前
【力扣76】最小覆盖子串
算法·leetcode·职场和发展
hjhcos1 小时前
【宝塔】局域网IP申请SSL证书,解决浏览器本地环境可以访问摄像头,发布环境不能访问摄像头的问题
网络协议·tcp/ip·ssl
近津薪荼1 小时前
优选算法——双指针5(单调性)
c++·学习·算法
2401_857683541 小时前
C++代码静态检测
开发语言·c++·算法
时艰.1 小时前
JVM 垃圾收集器(G1&ZGC)
java·jvm·算法
2401_838472511 小时前
内存泄漏自动检测系统
开发语言·c++·算法
m0_706653232 小时前
基于C++的爬虫框架
开发语言·c++·算法