- 思路
这道题其实可以看做是字符串分段问题,再输入的字符串中加入三个点,将字符串分割成四段,每一段必须合法,求所有可能的情况。本人使用的是回溯的方法,在第一段temp满足条件的情况下,找第二段temp1,在在第二段满足条件的情况下找temp2,temp3。这里需要注意的是temp3除了要用judge函数判断是否满足情况,还需要保证长度小于4,不加这个判断有可能出现temp3转成的数很大,超过了int的表示范围,但是转化成int后的大小小于256。当上述都满足时,才执行push_back操作。
- 代码
class Solution {
public:
/*
这里atoi可以将字符数组转化成整型数字;在使用to_string来将数字转化成字符串,然后通过比较这两个字符串的长度就可以判断是不是以0开头的不为0的数字了。很巧妙,值得记住,哈哈哈
*/
bool judge(string s){//判断这一段是否符合题义
return atoi(s.c_str()) <= 255 && s.length() == to_string(atoi(s.c_str())).length();
}
vector<string> restoreIpAddresses(string s) {
vector<string> vec;
int len = s.length();
for (int i = 0; i <= 2 && i < len - 3; i++) {
string temp = s.substr(0, i + 1);
if(judge(temp)) {
for (int j = i + 1; j <= i + 1 + 2 && j < len - 2; j++) {
string temp1 = s.substr(i + 1, j - i);
if (judge(temp1)) {
for (int k = j + 1; k <= j + 1 + 2 && k < len - 1; k++) {
string temp2 = s.substr(j + 1, k - j);
string temp3 = s.substr(k + 1, len - k - 1);
if (temp3.length() <= 3 && judge(temp2)&& judge(temp3)) {
vec.push_back(temp + "." + temp1 + "." + temp2 + "." + temp3);
}
}
}
}
}
}
return vec;
}
};
现在Ip地址是4段,使用for循环嵌套还勉强可以写出来,这道题更科学的做法是使用递归的方法,递归代码如下;
class Solution {
public:
bool judge(string s){
return atoi(s.c_str()) <= 255 && s.length() == to_string(atoi(s.c_str())).length();
}
void trans(string s, int num, string cache, vector<string> & vec){
//num代表的是已经检测完几段合格的,s表示还没有检测的字符串,cache是把检测
//到的合格的段组装成符合要求的缓存字符串。
if(num == 4){
if(s.length() == 0) vec.push_back(cache);
return;
}
int len = s.length();
for(int i = 0; i <= 2 && i < len; i++){
string temp = s.substr(0, i + 1);
if(judge(temp)){
trans(s.substr(i + 1, len - i), num + 1, cache + temp + (num == 3 ? "":"."), vec);
}
}
}
vector<string> restoreIpAddresses(string s) {
vector<string> vec;
string cache;
trans(s, 0, cache, vec);
return vec;
}
};