复原 IP 地址-LeetCode
93. 复原 IP 地址 - Restore IP Addresses
🎯 问题描述(来源于LeetCode)
描述:
给定一个只包含数字的字符串 s,用以表示一个 IP 地址,返回所有可能的有效 IP 地址(IPv4)。
有效 IP 地址由四个整数(每个在 0 到 255 之间)组成,且整数之间用 '.' 分隔。
不能包含前导零(例如 01 无效),但整数 0 本身是有效的。
说明:
- 字符串
s的长度在 1 到 20 之间。 - 需要枚举所有可能的分割方式,返回所有有效的 IP 地址。
示例:
- 示例 1:
1 | 输入: s = "25525511135" |
- 示例 2:
1 | 输入: s = "0000" |
- 示例 3:
1 | 输入: s = "101023" |
💻 解题思路
思路:回溯法(DFS)枚举分段
算法步骤
- 获取字符串长度
n,初始化结果列表ans和路径列表path(存储已确定的 IP 段)。 - 定义递归函数
dfs(i, cur),其中i表示当前扫描到的下标,cur表示当前正在累积的段(尚未决定切分):- 如果
i == n(扫描完所有字符):- 如果
cur非空(还有未切分的段),则将该段转为数字x,检查是否有效(无前导零且范围 0-255)。若有效,则将其加入path;若此时path长度正好为 4,则拼接成 IP 地址加入ans;最后回溯弹出path。 - 如果
cur为空(即没有剩余段),且path长度正好为 4,则直接拼接并加入ans。 - 返回。
- 如果
- 否则,进行两个分支:
- 不切分:将当前字符追加到
cur,递归dfs(i+1, cur+s[i])。 - 切分:如果
cur非空,则检查cur表示的整数是否有效(规则同上),且当前path长度小于 4。若有效,则将cur加入path,递归dfs(i+1, s[i])(开始新段),然后回溯弹出。
- 不切分:将当前字符追加到
- 如果
- 从
dfs(0, "")开始搜索。 - 返回
ans。
代码实现
1 | from typing import List |
📊 性能分析
- 时间复杂度:最坏情况下为 量级,实际上每个位置可切可不切,但通过有效性剪枝,通常远小于 。对于长度 ≤ 20 的字符串,本解法在 LeetCode 上可通过。
- 空间复杂度:,递归栈深度和路径存储。
思考
该解法通过两个参数 (i, cur) 巧妙地模拟了 IP 地址的分段过程。cur 累积当前段的数字,递归中同时尝试“继续延长当前段”和“结束当前段并开启新段”两种分支。
优点:
- 直接模拟了 IP 地址的构造过程,逻辑完整。
- 对有效段的检查(前导零和范围)做了细致处理。
注意事项:
- 检查有效段的条件
(m == 1 and x == 0) or 255 >= x >= 10**(m-1)能够正确处理0(长度为1且值为0)以及非零数字(无前导零且 ≤ 255)。例如"00"会被判定无效,因为m=2且10**(1)=10,0不在[10,255]内,同时也不是(m==1 and x==0),因此正确。 - 递归中“切分”分支必须在
cur非空时才能执行,避免了空段。 - 最终处理
i == n时,需要同时处理cur非空(最后一段)和cur为空(已经切分完所有段)两种情况,并且对于cur为空的情况,只需检查path长度是否为 4。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 笺札!






