题目链接:93. 复原 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
,用以表示一个 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”]
提示:
s
仅由数字组成回溯
这题和昨天的分割字符串很像,只是一些条件不同而已。题目是用 '.'
来分割的,而且分割后的字符串必须是有效的 ip
地址。而且对于分割后的字符串和原字符串相比只能多出三个点,其他的不能少也不能多。
读完题应该就能知道需要用递归写,所以就往递归上想。递归的深度应该是字符串的长度,当无法分割字符串时就必须结束递归,但是分割位置不能在字符串的末尾,那样就不符合题意了,所以递归的深度可以用分割次数。因为一个有效的 ip
地址只有三个点,所以只要字符串中存在了三个点,那么这个字符串就已经分割完成。递归的宽度应该很明显了,就是剩余未分割字符串的长度。
**那么该如何分割呢?**既然深度和宽度都已经知道了,那就思考如何利用这两个条件。深度很显然是用来判断递归的结束条件的。那么宽度应该就是用来将未分割的字符串遍历,寻找下一个正确的分割位置。**如何寻找?**将当前分割的字符串拿出来判断是否小于 256
,且没有前导零。如果满足则在该字符串后面加上点后进入下一层递归。
对于判断字符串是否小于 255
的方法有:
stoi(string),这个函数可以直接将 string
转为 int
型,头文件是
。这个函数也会进行强制转换,而且字符串的范围不能超过 int
的范围,否则会报错。这个函数是C++11的特性
判断函数,还可以直接写一个判断函数,函数里用循环遍历的方法把字符串转为数字
bool isip(string sb) {