思路:
- 回溯+剪枝
- 步骤,一般用vector比较多,两个起步,一个存临时值,一个存result,还有判断是否结束的begin和end
(1) 确定可以进入result的数据
(2) 进行剪枝操作
(3) 回溯
//(1)
if(....)
{
result.push_back();
return;
}
//(2)
if(...)
return;
if(...)
return;
//(3)
for(j){
temp.push_back(t);
IpAdd(s,begin+j,end,temp,re);
temp.pop_back();
}
代码
void IpAdd(string s,int begin,int end,vector<string> &temp,vector<string> &re){
if(begin==end&&temp.size()==4){
if(temp[0].size()<=3&&temp[1].size()<=3&&temp[2].size()<=3&&temp[3].size()<=3)//这句其实不用加,后面的回溯已经保证了所有的分段都是3以内,只是加上后leetcode跑的更快
{
string result = temp[0]+"."+temp[1]+"."+temp[2]+"."+temp[3];
re.push_back(result);
return;
}
}
//剪枝
if(begin==end&&(temp.size()>4||temp.size()<4))
return;
if(begin!=end&&(temp.size()>=4))
return;
//0开头的必须是单独的一位 xxx.0.xxx.0
int j=1;
if(s[begin]=='0'){
temp.push_back("0");
IpAdd(s,begin+1,end,temp,re);
temp.pop_back();
}
else
for(;j<=3;j++){
if(begin+j<=end){
string t = s.substr(begin,j);
if(atoi(t.c_str())<=255){
temp.push_back(t);
IpAdd(s,begin+j,end,temp,re);
temp.pop_back();
}
}
}