​LeetCode刷题实战93:复原IP地址

算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试。所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 !

今天和大家聊的问题叫做 复原IP地址,我们先来看题面:

https://leetcode-cn.com/problems/restore-ip-addresses/

Given a string s containing only digits, return all possible valid IP addresses that can be obtained from s. You can return them in any order.

A valid IP address consists of exactly four integers, each integer is between 0 and 255, separated by single dots and cannot have leading zeros. For example, "0.1.2.201" and "192.168.1.1" are valid IP addresses and "0.011.255.245", "192.168.1.312" and "192.168@1.1" are invalid IP addresses. 

题意

给定一个只包含数字的字符串,复原它并返回所有可能的 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 地址。

样例

示例 1:

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

示例 2:

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

示例 3:

输入:s = "1111"
输出:["1.1.1.1"]

示例 4:

输入:s = "010010"
输出:["0.10.0.10","0.100.1.0"]

示例 5:

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

解题

https://www.cnblogs.com/techflow/p/13554144.html

这道题的题意蛮新颖的,将字符串和ip地址结合在了一起,但是题目的内核说实话有些老生常谈了,都是那种将一个大局面转化成若干个小局面之和的情况。

我们之前做的全排列问题、八皇后问题等等都是这种,拿八皇后问题举例,看起来是我们要在棋盘上放置皇后。但实际上我们最终想要的结果是放置好了八个皇后之后的局面,这个局面是由放置了每一个皇后之后的小局面组合在一起构成的。所以本质上也可以看成是小局面组装成大局面的问题。

说了这么多,其实只为了说明一点,就是遇到这些大局面拆分小局面的问题,我们可以率先考虑搜索算法。搜索算法除了可以理解成在一个搜索空间或者是一棵搜索树当中寻找到解之外,也可以理解成可以用来寻找一些小局面的组合,让它们组合起来可以构成我们想要的大局面。

套用到这道题上来,很显然最后我们想要的大局面是合法的IP地址,而构成这个大局面的小局面则是构成IP地址的每一个数字。

这些都搞明白了之后,代码就很好写了:

class Solution:
    def restoreIpAddresses(self, s: str) -> List[str]:
        n = len(s)
        if n < 4 or n > 12:
            return []
        
        ret = []
        
        def dfs(cur, ips):
            # 如果递归结束,并且ips当中刚好存了4个ip
            # 则生成答案
            if cur >= n:
                if len(ips) == 4:
                    ret.append('.'.join(ips[:]))
                return
            
            # 遍历下一个ip是几位
            for i in range(cur, min(cur+3, n)):
                # 如果超过1位但是第一位是0,那么非法
                if s[cur] == '0' and i > cur:
                    return
                # ip必须小于等于255
                num = int(s[cur: i+1])
                if num > 255:
                    return
                
                # 回溯
                ips.append(s[cur: i+1])
                dfs(i+1, ips)
                ips.pop()
                
        dfs(0, [])
        return ret

好了,今天的文章就到这里,如果觉得有所收获,请顺手点个在看或者转发吧,你们的支持是我最大的动力。

上期推文:

LeetCode50-80题汇总,速度收藏!

LeetCode刷题实战81:搜索旋转排序数组 II

LeetCode刷题实战82:删除排序链表中的重复元素 II

LeetCode刷题实战83:删除排序链表中的重复元素

LeetCode刷题实战84: 柱状图中最大的矩形

LeetCode刷题实战85:最大矩形

LeetCode刷题实战86:分隔链表

LeetCode刷题实战87:扰乱字符串

LeetCode刷题实战88:合并两个有序数组

LeetCode刷题实战89:格雷编码

LeetCode刷题实战90:子集 II

LeetCode刷题实战91:解码方法

LeetCode刷题实战92:反转链表 II

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值