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

它真正考察的是:

  • 你能不能严格遵守规则
  • 你会不会遗漏边界
  • 你的代码是否清晰、可维护、可扩展
相关推荐
2401_854151551 分钟前
嵌入式传感器驱动开发深度解析——从 I2C/SPI 驱动到数据融合算法
驱动开发·算法
cpp_25013 分钟前
P6625 [省选联考 2020 B 卷] 卡牌游戏
数据结构·c++·算法·前缀和·贪心·洛谷题解·省选
Bug退散师24 分钟前
多路IO复用[select版TCP服务器与poll版TCP服务器]与常用网络编程函数详解
linux·服务器·c语言·网络·驱动开发·tcp/ip
石一峰69933 分钟前
驱动:私有数据为什么要在三个地方各挂一遍?
数据库·python·算法
卡提西亚2 小时前
leetcode-179. 最大数
python·算法
浩瀚地学2 小时前
【面试算法笔记】0302-哈希表-哈希表实现
java·经验分享·笔记·算法·面试
ECT-OS-JiuHuaShan2 小时前
严格证明:还原论是ASCII,整体论是UTF-8的历史意义和价值
开发语言·人工智能·算法·量子计算
ShallWeL2 小时前
【机器学习】(19)—— 数据特性与标签
人工智能·算法·机器学习
Frostnova丶2 小时前
(17)LeetCode 41. 缺失的第一个正数
数据结构·算法·leetcode