LeetCode 93. 复原IP地址 | Python

93. 复原IP地址


题目来源:力扣(LeetCode)https://leetcode-cn.com/problems/restore-ip-addressespython

题目


给定一个只包含数字的字符串,复原它并返回全部可能的 IP 地址格式。bash

有效的 IP 地址正好由四个整数(每一个整数位于 0 到 255 之间组成),整数之间用 '.' 分隔。app

示例:测试

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

解题思路


思路: 回溯spa

先看题目,题目要求的是给定一个只包含数字的字符串,复原返回全部可能的 IP 地址格式。至于 IP 地址的有效格式,是由 4 个整数(0~255),整数间用 '.' 分隔组成。.net

首先,根据题目,借助示例来看下:rest

s = "25525511135"

假设,给定的字符串如上面示例,那么咱们在第一个片断中,咱们有三种选择的可能:code

  • 选 '2';
  • 选 '25';
  • 选 '255'。

当第一片断选择完毕后,后续的三个片断,也以一样的形式去选择。可是咱们在选择的过程当中可能会出错,若是出错的话,此时咱们就须要撤销这项选择,转而去尝试另一个选择。blog

一样的,这里咱们的选择是有依据的,并不是随意选择。由题目,咱们也能够发现,每一个片断可选择的数字区间在 [0, 255] 之间,这里也表示长度不能超过 3。ip

这里还有个须要注意的,题目中并无明确指出。每一个片断中选择的数字是不能有前导 0 的,0 能够做为一个选择,可是不能出现 '0...' 这样的形式,这个也是在测试用例没过的时候发现的。╮(╯▽╰)╭

前面说了选择以及限制,那咱们如何才能确认,当选择完毕以后,选择组成的片断就是有效的?

  • 首先,要在前面所述的限制条件下进行选择;
  • 再来,题目要求复原,也就是,咱们选择完 4 个片断以后,必须是要用完全部字符的。
  • 若是选择完毕,可是没有用完字符,表示此项选择不符合,返回,回溯;若是先用完字符,可是没有找齐 4 个片断,一样回溯。
  • 由于复原的结果可能不止一种,当找到有效的组合,存入返回列表中,继续搜索直至全部可能的选择都尝试一次。

具体的代码实现以下(含注释)。

代码实现


class Solution:
    def restoreIpAddresses(self, s: str) -> List[str]:
        res = []
        # 这里初始化长度为 4 的列表,分别存储对应 4 个片断
        sub_res = [0] * 4

        def dfs(seg_id, seg_first):
            # 先看找到 4 个片断的状况
            # 这里可能出现字符彻底使用,以及未使用彻底的状况
            if seg_id == 4:
                # 使用彻底则添加到列表后返回
                if seg_first == len(s):
                    res.append('.'.join(str(seg)for seg in sub_res))
                # 未彻底使用则直接返回
                return
            
            # 若未找到 4 个片断,则继续查找
            # 这里要注意未找到 4 个片断却使用完字符的状况
            if seg_first == len(s):
                return

            # 不能存在前导 0,若是有 0,那么当前片断只能为单独 0
            if s[seg_first] == "0":
                sub_res[seg_id] = 0
                dfs(seg_id+1, seg_first+1)

            addr = 0
            # 每一个片断选择的状况
            for seg_last in range(seg_first, len(s)):
                # 这里用整型来表示,后面再转换为字符串类型,避免过于频繁的切片
                addr = addr * 10 + (ord(s[seg_last]) - ord('0'))

                # 大于 0,但小于等于 255 的状况
                if 0 < addr <= 255:
                    sub_res[seg_id] = addr
                    dfs(seg_id+1, seg_last+1)
                # 其余状况直接跳出循环
                else:
                    break
            
        dfs(0, 0)
        return res

实现结果


实现结果

欢迎关注


公众号 【书所集录

相关文章
相关标签/搜索