leetcode(力扣) 93. 复原 IP 地址(回溯)

题目描述

有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 ‘.’ 分隔。
例如:“0.1.2.201” 和 “192.168.1.1” 是 有效 IP 地址,但是 “0.011.255.245”、“192.168.1.312” 和 “192.168@1.1” 是 无效 IP 地址。
给定一个只包含数字的字符串 s ,用以表示一个 IP 地址,返回所有可能的有效 IP 地址,这些地址可以通过在 s 中插入 ‘.’ 来形成。你 不能 重新排序或删除 s 中的任何数字。你可以按 任何 顺序返回答案。

示例 1:
输入:s = “25525511135”
输出:[“255.255.11.135”,“255.255.111.35”]

示例 2:
输入:s = “0000”
输出:[“0.0.0.0”]

示例 3:
输入:s = “101023”
输出:[“1.0.10.23”,“1.0.102.3”,“10.1.0.23”,“10.10.2.3”,“101.0.2.3”]

思路分析

一定要。
先做 31. 分割回文串 再做这道题!!!
先做 31. 分割回文串 再做这道题!!!
先做 31. 分割回文串 再做这道题!!!

为啥呢~因为这道题是分割回文串的进阶版,改动的地方不多。

这道题也是分割,而且比上一个字符串分割感觉看上去要清晰一些,也是找组合的题嘛,回溯嘛,你要问我能不能暴力,我只能说, 可以暴力,看到有人这么做了,N层for,写到怀疑人生。

判断IP地址合法性的几个点:

  • IP地址一共是四段组成,中间三个 ‘.’ 分隔符。
  • 每一段有0-3个数字,范围是0-255左闭右闭。
  • 每小段中可以仅有0,但不能有向导0。
	def ip_check(ip):
        if ip == '0':return True  # 可以有0但不能前导0
        if ip[0] == '0':return False
        if int(ip) > 0 and int(ip) < 256:
            return  True
        else:
            return False

老规矩 回溯三步走:

1.确定函数参数:
这里的参数非常简单,就一个值,就是startindex,用于记录下次从哪里开始遍历。当然,这个参数确定要参考所写代码结构和所用编程语言。
2.确定终止条件:
如果path里有4个值了,也就是有4个小段ip了,并且 startindex 已经遍历到最后了,那么此时就加入到答案集res里。

这道题最后有两个小提示,

1 <= s.length <= 20
s 仅由数字组成

这就意味着在判断ip合法性的时候不需要判断是否是数字字符了。
还有一点就是题目要求不得删改原s字符中的数值,但是题目s所给长度范围又达到20个,而合法ip最大长度也就是每一段都是3个字符,所以最长也就是12个字符,在这里可以设置一个终止条件,就是所给s长度大于12,则直接return。

3.确定循环体:

这道题的循环体和上一道切割回文字符串的循环体基本一样,就是上一题添加答案集之前判断是不是回文的,这道题是判断IP地址是否合法。

完整代码

def restoreIpAddresses(self, s: str):
    path = []
    res = []
    def ip_check(ip):
        if ip == '0':return True  # 可以有0但不能前导0
        if ip[0] == '0':return False
        if int(ip) > 0 and int(ip) < 256:
            return  True
        else:
            return False
    def backtrack(startindex):
        # 确定终止条件
        if len(s) > 12:  # 剪枝,题目所给的s长度为1-20.
            return
        if len(path) == 4 and startindex == len(s):
            res.append(".".join(path[:]))
            return
        # 递归体
        for i in range(len(startindex,len(s))):
            ip = s[startindex,i+1]
            if ip_check(ip):
                path.append(ip)
            else:
                continue
            backtrack(i+1)
            ip.pop()
    backtrack(0)
    return res

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

深度不学习!!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值