【每天一道算法题4】【Python】复原ip地址

题目描述

给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。
示例:
输入: “25525511135”
输出: [“255.255.11.135”, “255.255.111.35”]
前不久在在线面试腾讯时碰到过这题,10分钟解题时间,当时一时紧张没写出来,只知道这个题目要用用到回溯算法,回来仔细想了2个解法。

解法一:回溯算法

分析:
ip地址格式规则:

  1. 包含4部分,如 xx.xx.xx.xx
  2. 每一部分可以是1位、2位、3位数字。
  3. 当大于2位时,不能以0开头,同时小于256。如1.01.0.1、1.256.1.1 都是不合法的

所以我们分4次去给的字符串取值,每次取值有三种情况:取1位、取2位、取3位,取值的同时要判断一下每一位是否符合条件3,然后结束的条件是取够4次,取够之后再判断一下剩余字符串是否还有值,有的话就说明本次取值路径不符合,直接return,如给的123456,某次取值路径是tmp=1.2.3.4,s=56,这就不符合规则了。

def get_all_ip(s: str) -> list:
    # 定义一个列表,用来存储生成的ip
    result = []
    
    def backtrack(s: str, tmp: str):
        """s 是需要回溯的字符串,tmp用来记录回溯“路径” """
        if tmp.count('.') == 4:  # 统计取了几次值,当tmp中有4个'.'时,表示已经取够了
            if not s:    # 这时候判断一下s是不是空,不是空的话就不符合,空的话就把tmp加入到结果集result
                result.append(tmp[:-1])
            return
        # 取1位,这时候长度大于0
        if len(s) > 0:
            # 把剩余的字符串即s[1:]继续递归,同时把s[0]加入到路径记录变量tmp
            backtrack(s[1:], tmp + s[0] + '.')
            
        # 取2位,这时候长度要大于1,且首位不为0
        if len(s) > 1 and s[0] != '0':
            # 把剩余的字符串即s[2:]继续递归,同时把s[:2]加入到路径记录变量tmp
            backtrack(s[2:], tmp + s[:2] + '.')
            
        # 取3位,这时候长度要大于2,且首位不为0,且要小于256
        if len(s) > 2 and s[0] != '0' and int(s[:3]) < 256:
            # 把剩余的字符串即s[3:]继续递归,同时把s[:3]加入到路径记录变量tmp
            backtrack(s[3:], tmp + s[:3] + '.')
    backtrack(s, '')
    return result
解法二:暴力法
class Solution:
    def restoreIpAddresses(self, s: str) -> List[str]:
        n = len(s)
        res = []
		# 判读是否满足ip的条件
        def helper(tmp):
            if not tmp or (tmp[0] == "0" and len(tmp) > 1) or int(tmp) > 255:
                return False
            return True
		# 三个循环,把数字分成四份
        for i in range(3):
            for j in range(i + 1, i + 4):
                for k in range(j + 1, j + 4):
                    if i < n and j < n and k < n:
                        tmp1 = s[:i + 1]
                        tmp2 = s[i + 1:j + 1]
                        tmp3 = s[j + 1:k + 1]
                        tmp4 = s[k + 1:]
                        # print(tmp1, tmp2, tmp3, tmp4)

                        if all(map(helper, [tmp1, tmp2, tmp3, tmp4])):
                            res.append(tmp1 + "." + tmp2 + "." + tmp3 + "." + tmp4)
        return res


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值