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

它真正考察的是:

  • 你能不能严格遵守规则
  • 你会不会遗漏边界
  • 你的代码是否清晰、可维护、可扩展
相关推荐
求梦8203 分钟前
【力扣hot100题】缺失的第一个正数(12)
数据结构·算法·leetcode
阿巴~阿巴~7 分钟前
从不可靠到100%可靠:TCP与网络设计的工程智慧全景解析
运维·服务器·网络·网络协议·tcp/ip·智能路由器
黎雁·泠崖17 分钟前
二叉树实战进阶全攻略:从层序遍历到OJ题深度解析
c语言·数据结构·leetcode
散峰而望19 分钟前
【算法竞赛】顺序表和vector
c语言·开发语言·数据结构·c++·人工智能·算法·github
千金裘换酒19 分钟前
LeetCode 回文链表
算法·leetcode·链表
CSDN_RTKLIB20 分钟前
【std::map】与std::unordered_map差异
算法·stl·哈希算法
FL1717131420 分钟前
Geometric Control
人工智能·算法
老鼠只爱大米23 分钟前
LeetCode算法题详解 283:移动零
算法·leetcode·双指针·快慢指针·移动零·move zeroes
过河卒_zh156676628 分钟前
喜讯:第十五批生成合成类算法备案备案号公布
人工智能·算法·aigc·生成式人工智能·算法备案
cpp_250132 分钟前
B3927 [GESP202312 四级] 小杨的字典
数据结构·c++·算法·题解·洛谷