回溯算法:复原IP
思路:与上一篇:回溯算法:分割回文串异曲同工之妙,同样是切割字符串的思想,本体在剪枝方面可以进一步优化,当有不符合IP的字符串出现时,可以直接跳过本层所有循环,即break
,但分割回文串则不可以,因为你不知道本层中加入下一个字符后是否可以构成回文串,因此不能跳出本层循环,即循环跳出条件为continue
class Solution {
public:
vector<string> res;
string path;
vector<string> restoreIpAddresses(string s) {
if(s.empty())
return res;
int startIndex = 0;
int pointNum = 0;
backtrack(s, startIndex, pointNum);
return res;
}
bool isIP(string s)
{
if(s.empty())
return false;
stringstream ss(s);
int number = 0;
ss >> number;
if(s.size() != 1 && s[0] == '0')
return false;
else if(number > 255)
return false;
else
return true;
}
void backtrack(string s, int startIndex, int pointNum)
{
//退出条件
if(pointNum == 3)
{
if(isIP(s.substr(startIndex)))
{
string tmp = path;
tmp += s.substr(startIndex);
res.push_back(tmp);
}
return;
}
//单层节点
for(int i = startIndex; i < s.size(); i++)
{
string tmp = s.substr(startIndex, i - startIndex + 1);
if(isIP(tmp))
{
path = path + tmp + '.';
pointNum++;
//递归到下层节点
backtrack(s, i + 1,pointNum);
//回溯
pointNum--;
path.erase(path.size() - 1 - tmp.size());
}
//直接跳过本层循环
else
{
break;
}
}
}
};