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 地址》这道题,非常不像"刷题",但非常像"真实工作"

它真正考察的是:

  • 你能不能严格遵守规则
  • 你会不会遗漏边界
  • 你的代码是否清晰、可维护、可扩展
相关推荐
HXhlx2 小时前
CART决策树基本原理
算法·机器学习
Wect2 小时前
LeetCode 210. 课程表 II 题解:Kahn算法+DFS 双解法精讲
前端·算法·typescript
颜酱3 小时前
单调队列:滑动窗口极值问题的最优解(通用模板版)
javascript·后端·算法
Gorway10 小时前
解析残差网络 (ResNet)
算法
拖拉斯旋风10 小时前
LeetCode 经典算法题解析:优先队列与广度优先搜索的巧妙应用
算法
Wect10 小时前
LeetCode 207. 课程表:两种解法(BFS+DFS)详细解析
前端·算法·typescript
灵感__idea1 天前
Hello 算法:众里寻她千“百度”
前端·javascript·算法
Wect1 天前
LeetCode 130. 被围绕的区域:两种解法详解(BFS/DFS)
前端·算法·typescript
NAGNIP2 天前
一文搞懂深度学习中的通用逼近定理!
人工智能·算法·面试
颜酱2 天前
单调栈:从模板到实战
javascript·后端·算法