一、题目描述
有效 IP 地址 正好由四个整数(每个整数位于 0
到 255
之间组成,且不能含有前导 0
),整数之间用 '.'
分隔。
例如:"0.1.2.201"
和 "192.168.1.1"
是 有效 IP 地址,但是 "0.011.255.245"
、"192.168.1.312"
和 "192.168@1.1"
是 无效 IP 地址。
给定一个只包含数字的字符串 s
,用以表示一个 IP 地址,返回所有可能的有效 IP 地址,这些地址可以通过在 s
中插入 '.'
来形成。你 不能 重新排序或删除 s
中的任何数字。你可以按 任何 顺序返回答案。
示例 1
输入:s = "25525511135"
输出:["255.255.11.135","255.255.111.35"]
示例 2
输入:s = "0000"
输出:["0.0.0.0"]
示例 3
输入:s = "101023"
输出:["1.0.10.23","1.0.102.3","10.1.0.23","10.10.2.3","101.0.2.3"]
提示:
1 <= s.length <= 20
s 仅由数字组成
二、代码
代码如下:
class Solution:
def restoreIpAddresses(self, s: str) -> List[str]:
def judgment(ip):
nums = ip.split(".")
for i in range(len(nums)):
if int(nums[i]) > 255:
return False
if nums[i][0] == "0" and len(nums[i])>1:
return False
return True
list_s = list(s)
print(list_s)
length = len(list_s)
#['1', '0', '1', '0', '2', '3']
result = []
if length > 12 or length < 4:
print("超出ip地址长度范围,为无效ip")
return []
if length == 12:
print("只有一种组合情况") # XXX.XXX.XXX.XXX
ip = f"{s[0:3]}.{s[3:6]}.{s[6:9]}.{s[9:12]}"
if judgment(ip) :
result.append(ip)
print(result)
return result
else:
print(f"{ip}为无效ip")
if length == 4:
print("只有一种组合情况") # X.X.X.X
ip = f"{s[0]}.{s[1]}.{s[2]}.{s[3]}"
result.append(ip)
print(result)
return result
for i in range(1,length-2):
for j in range(i+1,length-1):
for k in range(j+1,length):
ip = f"{s[:i]}.{s[i:j]}.{s[j:k]}.{s[k:]}"
if judgment(ip):
result.append(ip)
print(result)
return result
三、解题思路
本题的在看上去一眼时可能想到的解法是回溯法,但本题解这里则不采用回溯法,在解决本题之前,我们可以将本题意理解为:“在字符串s中插入三个 ‘.’
,然后找出所有有效的ip地址”,这样一来,我们需要做的就是往字符串s中依次添加3个‘.’
即可,最后判断当前的ip地址是否有效,如果有效则加入result
数组中,反之亦然。
本题解的关键是如何完整全部地插入三个‘.’
,这里采用了3重for循环进行遍历,每一重循环相当于插入了一个‘.’
,第一次插入‘.’
时从下标1开始,因为‘.’
不能插入字符串s的两端。之后插入‘.’
时都在前一次插入的基础上向后继续插入;当三个点都插入时,建立ip并传给judgement函数判断,如果有效则加入result。最后返回result数组即可。
本题解使用一个专门的函数judgement(ip)
去判断ip地址是否有效,判断标准如下:
①用‘.’
将ip地址分为的4部分,判断每一部分的值是否大于255,如果大于则返回False;
②判断前导0的情况,每一部分的第一个字符如果是“0”且该部分除“0”以外仍然存在数字(即该部分长度>1),则返回False。
③最后如果4个部分都遍历完成且没有问题,则返回True。