一日两更。
题目:
给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。
有效的 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 '.' 分隔。
思路:
相当于遍历一棵树,依次分段向下搜索,并在适当适合予以剪枝从而减小搜索规模。
IP地址一共四段。
1.一旦搜索到当前位置的值是0,基于题目要求没有前导0,那么这一段实际上就是0,就可以在剩下的字符串搜索其他段的值(此时可以采取的剪枝策略可以是长度,如果长度超过剩余位数的最大长度,可以不再向下搜索,懒,没写……)。
2.一旦搜索到当前位置的值不是0,小于2(就是1了),基于题目要求,我们可以在长度允许的范围内,通过截取对应1位,2位,3位作为该段内容,并在此基础上继续向下遍历,同时通过长度进行剪枝。
3.一旦搜索到当前位置的值是2,主要判断一下3位时是否小于等于255,其他参考第2条,同理,当前位置大于2时,最多也只能有1位或2位,就不存在3位的可能性了。
4.当我们遇到当前位置已经达到要复原的字符串尾部且已经划分出了4段ip的时候,就可以把答案插入到vector中了。
代码:
class Solution {
public:
vector<string> ans;
void subfuc(string str,string s,int loc,int j){
if(loc<str.length()&&j<4){
if(str[loc]=='0'){
s+="0";//没有前导0
loc++;
if(j<3)s+=".";
j++;
subfuc(str,s,loc,j);
}else if(str[loc]<'2'){
s+=str[loc];
loc++;
if(j<3)subfuc(str,s+".",loc,j+1);
else subfuc(str,s,loc,j+1);
if(loc<str.length()){
s+=str[loc];
loc++;
if(j<3)subfuc(str,s+".",loc,j+1);
else subfuc(str,s,loc,j+1);
if(loc<str.length()){
s+=str[loc];
loc++;
if(j<3)subfuc(str,s+".",loc,j+1);
else subfuc(str,s,loc,j+1);
}
}
}else if(str[loc]>'2'){
s+=str[loc];
loc++;
if(j<3)subfuc(str,s+".",loc,j+1);
else subfuc(str,s,loc,j+1);
if(loc<str.length()){
s+=str[loc];
loc++;
if(j<3)subfuc(str,s+".",loc,j+1);
else subfuc(str,s,loc,j+1);
}
}else{
s+=str[loc];
loc++;
if(j<3)subfuc(str,s+".",loc,j+1);
else subfuc(str,s,loc,j+1);
if(loc<str.length()){
s+=str[loc];
loc++;
if(j<3)subfuc(str,s+".",loc,j+1);
else subfuc(str,s,loc,j+1);
if(loc<str.length()&&(str[loc-1]<'5'||(str[loc-1]=='5'&&str[loc]<='5'))){
s+=str[loc];
loc++;
if(j<3)subfuc(str,s+".",loc,j+1);
else subfuc(str,s,loc,j+1);
}
}
}
}else{
if(loc==str.length()&&j==4)ans.push_back(s);
}
}
vector<string> restoreIpAddresses(string s) {
string str="";
subfuc(s,str,0,0);
return ans;
}
};