恢复IP地址
之前面试问到的一个算法题,也是Lintcode上的一道题。
题:字符串如 "25525511111",得到所有有效IP的组合,如["255.255.11.111","255.255.111.11"]。
解析:一个有效的IP分成4段,每一field的长度是1到3之间,且整数值要大于等于0,且小于256;此外,如果字段位数大于1,那么第一个值不能为0,比如02,这就是不合法的。
代码:
1、穷举法。
一个IP分成四部分,那么我们在字符串中该如何获得呢?
在一个字符串中,我们找5个点:0,i,j,k,len(string)。那[0:i],[i:j],[j:k],[k:len] 这四部分就是我们获得的ip字段,当然我们还是要对每一个进行如上的有效性判断,如果有效,才算是合法的ip。
看上面的那几个分片,间距都应该小于4。我们就用穷举的方法进行遍历。见代码:
#判断有效性
def isValid(ip_fields_tuple):
for field in ip_fields_tuple:
integer = int(field)
if integer >255 or integer < 0:
break
if len(field) > 1 and field[0] == '0':
break
if len(field) > 3:
break
else :
#如果没有break,就证明有效,直接执行else的语句。
return True
return False
def RestoreIpAddr(ip_string):
length = len(ip_string)
i = 1
addrs = []
while i < 4 and i < length-2:
j = i + 1
while j < i+4 and j < length-1:
k = j + 1
while k < j+4 and k < length:
first,second,third,fourth = ip_string[0:i],ip_string[i:j],ip_string[j:k],ip_string[k:length]
if isValid((first,second,third,fourth)):
addrs.append(".".join((first,second,third,fourth)))
k += 1
j += 1
i += 1
return addrs
现在采用其他的方法,递归调用。有点像字符串的全排列,但要比字符串全排列简单一些,不需要字符交换。
def isValidSingleField(field):
integer = int(field)
if integer >255 or integer < 0:
return False
if len(field) > 1 and field[0] == '0' or len(field)>3:
return False
return True
def RecurseRestoreIpAddr(ipstring):
addrs, temp_ip_array = [], []
find_field(ipstring,temp_ip_array,addrs,0)
return addrs
def find_field(ipstring,temp_ip_array,result,index):
if len(temp_ip_array) == 4:
if index != len(ipstring):
return
ip = ".".join(temp_ip_array)
#print ip
result.append(ip)
return
i = index
while i< index+3 and i < len(ipstring):
field = ipstring[index:i+1]
if isValidSingleField(field):
temp_ip_array.append(field)
#递归调用,有点类似字符串的全排列,但要比字符串全排列要简单,不用交换。
find_field(ipstring,temp_ip_array,result,i+1)
#删除当前层的元素
temp_ip_array.pop()
i += 1
--------EOF---------
微信分享/微信扫码阅读
微信分享/微信扫码阅读