LeetCode (力锋) 93 questions: Recover IP address - backtracking solution with detailed notes

题目描述

Given a string s consisting only of numbers representing an IP address, return all possible valid IP addresses from s , and you can return the answers in any order.
A valid IP address consists of four integers (each integer is between 0-255 and cannot contain a leading 0), and the integers are separated by '.'. For example: "0.1.2.201" and "192.168.1.1" are valid IP addresses, but "0.011.255.245", "192.168.1.312" and "[email protected]" are invalid IP addresses.

输入输出示例

输入: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"]

思路分析

Generally, when I see string problems, it is easy to think of using stacks, double pointers, recursion, backtracking, etc. to solve these problems. Today I saw this topic-find all valid IP addresses, then consider backtracking and traversing all the situations, and then filter Qualified IP address.
Because IP consists of four parts, we only need to select four parts, and then judge whether each part meets the conditions of a valid IP. There is a special situation here that needs to be judged separately, that is, when the current starting character is "0", it needs to become a part by itself (the leading part of the effective IP is not 0).
First, we start to judge from the first element of the string, select the valid first part, then set the initial judgment character to the length of the first part plus 1, and then use recursion to filter out the second part of the valid characters from the remaining characters Part, recursively four times in turn, if the four parts selected all meet the requirements of valid IP, and the splicing is exactly equal to the string s, then these four parts are separated by '.' to form a valid IP address. Let's take a look at the code and comments to make your thinking clearer.

代码

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 

运行结果

insert image description here
参考

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

Guess you like

Origin blog.csdn.net/Just_do_myself/article/details/118468335