1 问题
给定一个只包含数字的字符串,复原它并返回所有可能的 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 地址。
示例 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”]
提示:
0 <= s.length <= 3000
s 仅由数字组成
2 解法
class Solution {
public:
vector<string> res; //记录结果
// startIndex: 搜索的起始位置,pointNum:添加逗点的数量
void backtracking(string& s, int startIndex, int pointNum)
{
if(pointNum == 3)
{
//判断第四个子字符串是否合法,如果合法则放进res
if(isValid(s, startIndex, s.size() - 1))
res.push_back(s);
return;
}
for(int i = startIndex; i < s.size(); i++)
{
// 判断 [startIndex,i] 这个区间的子串是否合法
if(isValid(s, startIndex, i))
{
// 在i的后面插入一个逗点
s.insert(s.begin() + i + 1, '.');
//逗点数量加1
pointNum++;
//递归
backtracking(s, i + 2, pointNum); //插入逗点之后下一个子串的起始位置为i+2
//回溯
s.erase(s.begin() + i + 1); //擦除逗点
pointNum--;
}
else
break; //本次不符合,则后面切割符合不符合不再考虑,结束该层循环
}
}
bool isValid(const string& s, int begin, int end)
{
if(begin > end)
return false;
//1.以0开头的数字不合法
if(s[begin] == '0' && begin != end) //begin != end 排除0.0.0.0
{
return false;
}
//2.每个字符不属于0-9,或该区间的数字大于255不合法
int num = 0; //统计该段数字的和
for(int i = begin; i <= end; i++)
{
//每个字符不属于0-9
if(s[i] > '9' || s[i] < '0')
return false;
num = num * 10 + (s[i] - '0');
//该区间的数字大于255不合法
if(num > 255)
return false;
}
return true;
}
vector<string> restoreIpAddresses(string s) {
backtracking(s, 0, 0);
return res;
}
};