LeetCode(力扣) 93题:复原IP地址----回溯求解附带详细注释

题目描述

给定一个只包含数字的字符串 s ,用以表示一个IP地址,返回所有可能从 s 中获得的有效IP地址,你可以按照任何顺序返回答案。
有效IP地址由四个整数 (每个整数位于0-255之间,且不能含有前导 0 ) 组成,整数之间使用 ‘ . ’ 分隔。例如:“0.1.2.201” 和 “192.168.1.1” 是 有效 IP 地址,但是 “0.011.255.245”、“192.168.1.312” 和 “[email protected]” 是 无效 IP 地址。

输入输出示例

输入:s = "25525511135"
输出:["255.255.11.135","255.255.111.35"]

输入:s = "0000"
输出:["0.0.0.0"]

输入:s = "101023"
输出:["1.0.10.23","1.0.102.3","10.1.0.23","10.10.2.3","101.0.2.3"]

思路分析

一般我看到字符串的问题容易想到用栈、双指针、递归、回溯等这些方法来解决,今天看到这个题目——找出所有有效的IP地址,那么考虑回溯遍历所有的情况,然后筛选出合格的IP地址。
因为IP由四个部分组成,那我们只需要选出四个部分,然后判断每个部分是否符合有效IP的条件即可。在这里有一种特殊的情况需要单独判断一下,就是当前起始字符为 “0” 的时候,它需要自己成为一个部分 (有效IP的前导不为0)。
首先我们从字符串第一个元素开始判断,选出有效的第一部分,然后将起始的判断字符设定为第一部分的长度加1,然后使用递归在剩余字符中筛选出第二部分有效的部分,依次递归四次,如果筛选出的四部分全都符合有效IP的要求,而且拼接起来正好等于字符串 s,那将这四部分用 ‘ . ’ 分隔开形成有效的IP地址。下面看一下代码和注释大家思路会更清晰一些。

代码

class Solution:
    def restoreIpAddresses(self, s: str) -> List[str]:
        n = len(s)
        # 首先判断字符串的长度,看其长度是否满足最短和最长要求,不满足直接返回空
        if n < 4  or n > 12:
            return []

        # IP总共4部分, 需进行4次判断
        SEG_COUNT = 4
        ans = list()
        segments = [0] * SEG_COUNT # 用于存储当前判断过程中的IP结果
        # 递归函数, seg_id为当前判断阶段, seg_start为当前开始判断的字符串位置
        def dfs(seg_id, seg_start):
            # 如果当前为判断的第4阶段,并且当前开始判断的位置为字符串的最后一
            # 个元素,那么当前情况符合IP地址形式,加入结果列表ans
            if seg_id == 4:
                if seg_start == n:
                    IP = '.'.join(str(seg) for seg in segments)
                    ans.append(IP)
                return
            # 如果当前起始位置位于字符串尾部,说明已经判断完整个字符串,返回
            if seg_start == n:
                return
            # 如果当前起始位置的字符为 “0”,则直接当作IP的一部分,进入下一阶段
            if s[seg_start] == '0':
                segments[seg_id] = '0'
                dfs(seg_id + 1, seg_start + 1)
            # 如果当前起始位置不为 “0”
            addr = 0
            for seg_end in range(seg_start, n):
            	# 判断当前整数是否在[0, 255]中
                addr = addr * 10 + (ord(s[seg_end]) - ord('0'))
                if 0 < addr <= 0xFF:
                    segments[seg_id] = addr
                    dfs(seg_id + 1, seg_end + 1)
                else:
                    break
        dfs(0, 0)
        return ans 

运行结果

在这里插入图片描述
参考

https://leetcode-cn.com/problems/restore-ip-addresses/solution/fu-yuan-ipdi-zhi-by-leetcode-solution/

猜你喜欢

转载自blog.csdn.net/Just_do_myself/article/details/118468335
今日推荐