首先需要知道IP地址的特性,总共有四段,每段的取值都在[0,255]之间,四段之间用3个‘.’隔开。目标就是如何放置这3个分隔符,使得IP地址是合法的,然后把合法的IP地址记录下来。
方法一 暴力解法。四段的长度都有取1~3的可能性,遍历所有的情况,记录合法IP地址。当然类似000,001,00,010这种肯定是不合法的段,将字符串段转换成整数,又把整数转换成字符串,就可以把间接的把这些长度上有效但是不符合实际的情况消除掉。
class Solution {
public:
vector<string> restoreIpAddresses(string s) {
vector<string> ves;
string str;
for(int a=1;a<=3;a++)
for(int b=1;b<=3;b++)
for(int c=1;c<=3;c++)
for(int d=1;d<=3;d++)
{
if(a+b+c+d==s.size()){
int A=stoi(s.substr(0,a));
int B=stoi(s.substr(a,b));
int C=stoi(s.substr(a+b,c));
int D=stoi(s.substr(a+b+c,d));
if(A<=255&&B<=255&&C<=255&&D<=255){
if((str=to_string(A)+'.'+to_string(B)+'.'+to_string(C)+'.'+to_string(D)).size()==s.size()+3){
ves.push_back(str);
}
}
}
}
return ves;
}
};
方法二 递归方法,总共有4段,先生成第一段,再递归生成下一段,代码如下:
class Solution {
public:
vector<string> restoreIpAddresses(string s) {
vector<string> ves;
if(s.size()>12||s.size()<4){
return ves;
}
restore(s,4,"",ves);
return ves;
}
void restore(string s,int k,string str,vector<string>& ves)
{
if(k==0&&s.empty()){//四段已经生成好
ves.push_back(str);
}else{
for(int i=1;i<=3;i++)
{
if(s.size()>=i&&isvalid(s.substr(0,i)))
{
restore(s.substr(i),k-1,str+s.substr(0,i)+(k==1?"":"."),ves);
}
}
}
}
bool isvalid(string str)
{
if((str.size()>1&&str[0]=='0')||stoi(str)>255||stoi(str)<0){// 两位以上时不能以0为开头,值不能超过255
return false;
}
return true;
}
};