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

它真正考察的是:

  • 你能不能严格遵守规则
  • 你会不会遗漏边界
  • 你的代码是否清晰、可维护、可扩展
相关推荐
野犬寒鸦4 分钟前
JVM垃圾回收机制面试常问问题及详解
java·服务器·开发语言·jvm·后端·算法·面试
风酥糖11 分钟前
Godot游戏练习01-第16节-游戏中的状态机
算法·游戏·godot
参.商.13 分钟前
【Day45】647. 回文子串 5. 最长回文子串
leetcode·golang
budingxiaomoli14 分钟前
优选算法--优先级队列(堆)
算法
Trouvaille ~16 分钟前
【优选算法篇】哈希表——空间换时间的极致艺术
c++·算法·leetcode·青少年编程·蓝桥杯·哈希算法·散列表
bbbb36516 分钟前
算法调优的多目标优化与性能平衡模型的技术8
算法
Fcy64817 分钟前
与二叉树有关算法题
算法·深度优先
️是7820 分钟前
信息奥赛一本通—编程启蒙(3346:【例60.3】 找素数)
数据结构·c++·算法
captain37621 分钟前
map和set
数据结构·算法
Java成神之路-22 分钟前
DNS 与 CDN 底层原理深度剖析:从域名解析到内容分发全链路解析
网络·网络协议·tcp/ip