HJ90. 合法IP
题目描述
判断输入的字符串是否为合法的 IPv4 地址。
合法的 IPv4 由 4 段组成,每段为 0~255 的十进制整数,段之间用 . 分隔。
输入格式
一行字符串,形如 192.168.1.1。
输出格式
合法输出 YES,否则输出 NO。
示例
示例 1
输入:
10.137.9.5
输出:
YES
示例 2
输入:
256.1.1.1
输出:
NO
解题思路
第一步:理解问题本质
IPv4 校验 = 恰好 4 段 + 每段是 0~255 的十进制整数。逐个条件检查,任何一个不满足即非法。
第二步:暴力解法
用正则做严格校验,表达式复杂且难以覆盖所有边界(空段、前导零、非数字等),容易漏判。
第三步:最优解法(逐条件模拟)
按顺序检查:
split('.')后必须恰好 4 段- 每段必须
isdigit()(纯数字且非空) - 每段数值必须
0 <= int <= 255
parts = ip.split('.')
if len(parts) != 4:
return False
for part in parts:
if not part.isdigit() or (len(part) > 1 and part[0] == '0'):
return False
if not (0 <= int(part) <= 255):
return False
return True
完整代码实现
算法可视化 · 逐帧回放这道题的代码7 帧 · 录制输入
import sys
def is_valid_ip(ip: str) -> bool:
parts = ip.split('.')
if len(parts) != 4:
return False
for part in parts:
if not part.isdigit():
return False
if len(part) > 1 and part[0] == '0': # 前导零非法
return False
if not (0 <= int(part) <= 255):
return False
return True
def solve():
ip = sys.stdin.readline().strip()
print("YES" if is_valid_ip(ip) else "NO")
if __name__ == "__main__":
solve()
示例推演
以 256.1.1.1 为例:
- 分割 →
['256','1','1','1'],恰好 4 段 ✓ - 段
256:是数字,但256 > 255✗
结果:NO。
复杂度分析
| 解法 | 时间复杂度 | 空间复杂度 | 说明 |
|---|---|---|---|
| 正则校验 | O(n) | O(1) | 表达式复杂难维护 |
| 逐条件模拟 | O(n) | O(n) | 清晰直观 |
n 为 IP 字符串长度
易错点总结
1. 段数必须恰好 4
1.2.3(3 段)或 1.2.3.4.5(5 段)都非法,必须先检查段数。
2. 每段必须纯数字
a.b.c.d 这类含字母的非法,用 isdigit() 检查。
3. 空段处理
1..2.3 中空段 .split('.') 会产生空字符串,空串 isdigit() 为 False,正确判非法。
4. 前导零
每段不能有前导零(除非整段就是 0)。如 01.2.3.8 的 01、1.2.3.04 的 04 都非法。需额外判断 len(part) > 1 and part[0] == '0'。
5. 数值范围
每段必须 0 <= x <= 255,256 超界非法。
扩展思考
- 更严格的 IP 校验还会排除前导零(如
01.2.3.4非法),本题即采用该规则。不同平台规则略有差异,实现前需确认。 - 可推广到校验 IPv6 或子网掩码。