Given a string containing only digits, restore it by returning all possible valid IP address combinations.
For example:
Given "25525511135"
,
return ["255.255.11.135", "255.255.111.35"]
. (Order does not matter)
不能出现:1.01.1.1的含有前缀0的情况!代码中有处理
此题使用回溯法。(枚举+剪枝)
要充分理解递归树!
vector<string> restoreIpAddresses(string s) {
string ip;
vector<string> result;
dfs_IpAddresses(s,0,0,ip,result);
return result;
}
void dfs_IpAddresses(string s,int start,int step,string ip,vector<string> &result)
{
if(step >= 4 && start == s.size())
{
//去除最后一个字符点号(.)
ip.erase(ip.size()-1);//会多加一个'.',所以的去掉!
result.push_back(ip);
return;
}
else
{
int num = 0;
//减枝函数-一个最小,一个最大剩余字符数!
if((s.size() - start ) < (4 - step)) return ;//剩余字符不能少于ip中每个位一位字符
if((s.size() - start ) > 3*(4 - step))return ;//剩余字符最多不多于ip中每个位3位字符
for(int i = 0; i < 3;i++)
{
num = num*10 + ( s[start + i] - '0' );//用于判断是否大于最大数255!
if(num > 255)continue;
//此处ip为需要变动加入到ip 中为递归树同层兄弟节点使用!
ip = ip+s[start + i];//个人由于没注意:此次之前写错了,直接全由dfs_IpAddresses处理而出错!(同层需使用所以放在外层处理!)
//不能在此处处理含有前缀为0的!//此次已处理当前整体为0,可能被去掉!
//此处ip+'.'//为当前路径加入'.',为虚的不影响同层兄弟节点使用ip。
dfs_IpAddresses(s,start+i+1,step+1,ip+'.',result);//处理ip地址!
if(num == 0) return ; //当前层全不要!不能有前缀为0的。如上面提到!
}
}
}
第二次
vector<string> restoreIpAddresses(string s)
{
if (s.size() < 3)
{
return vector<string>();
}
vector<string> res;
string res_one;
restore_ip(s,0,0,res,res_one);
return res;
}
void restore_ip(string &str,int level,int pos,vector<string> &res,string res_one)
{
if (level >= 4)//ip最多4个
{
if (pos == str.size())//只有长度刚好才取,否则重复
{
res.push_back(res_one.substr(0,res_one.size()-1));
}
return ;
}
int num = 0;
for (int i = pos;i < pos+3;i++)//枚举长度 1 - 3
{
if (i >= str.size())//检查是否长度太短
{
return ;
}
num = num*10 + str[i] - '0';
if ( num > 255)//处理数字大于255的,ip地址固有限制
{
return ;
}
if (i-pos >= 1 &&str[pos] == '0')//处理0为前缀的情况!!
{
return;
}
restore_ip(str,level+1,i+1,res,res_one+str.substr(pos,i-pos+1)+'.');
}
}
不处理前缀0的情况,以下是处理的代码。
//需注意001 ,01 需去掉 ,而0,10,100需保存,故而其实只需判断第一个为0的情况,但是还有一种为0但不能去掉,所以长度>=2 才处理判断!
{
return;
}
大家把以上这部分代码注释会出现如下错误:
Input: | "010010" |
Output: | ["0.1.0.010","0.1.00.10","0.1.001.0","0.10.0.10","0.10.01.0","0.100.1.0","01.0.0.10","01.0.01.0","01.00.1.0","010.0.1.0"] |
Expected: | ["0.10.0.10","0.100.1.0"] |