经典DFS的思路。时间O(n^3) (??),空间O(n)。
需要注意的问题:IP地址的每一部分如果为0,则必须只有一位‘0’,如果不为0,则不能包含前缀‘0’。
class Solution {
public:
vector<string> restoreIpAddresses(string s) {
vector<string> result;
vector<string> path;
dfs(s, 0, path, result);
return result;
}
void dfs(string s, int pos, vector<string> &path, vector<string> &result)
{
if(pos == s.size() && path.size() == 4)
{
string out;
out += path[0];
out += ".";
out += path[1];
out += ".";
out += path[2];
out += ".";
out += path[3];
result.push_back(out);
}
else
{
if(path.size() == 4) return;
for(int i=pos; i<s.size() && i<pos+3; ++i)
{
string sub = s.substr(pos, i-pos+1);
int t = stoi(sub);
if((t > 0 && t <= 255 && sub[0] != '0') || (t==0 && i==pos))
{
path.push_back(sub);
dfs(s, i+1, path, result);
path.pop_back();
}
}
}
}
};
非递归版。 注意搜索的终止条件(如果点的个数包括首尾大于5而后面还有其他的数字)
class Solution {
public:
vector<string> restoreIpAddresses(string s) {
vector<string> result;
stack<int> stack;
vector<int> path;
stack.push(0);
while(!stack.empty())
{
int cur = stack.top();
path.push_back(cur);
if(path.size() == 5 && path[4] == s.size())
{
string res = genIP(s, path);
result.push_back(res);
}
else if(path.size() < 5)
{
for(int i=cur+1; i<=s.size() && i<=cur+3; i++)
{
if(valid(s.substr(cur, i-cur)))
stack.push(i);
}
}
while(!stack.empty() && stack.top() == path.back())
{
stack.pop();
path.pop_back();
}
}
return result;
}
bool valid(string s)
{
if(s[0] == '0' && s.size() > 1) return false;
int value;
stringstream ss(s);
ss >> value;
if(value >= 0 && value <= 255)
return true;
else
return false;
}
string genIP(string s, vector<int> path)
{
string result(s);
int shift = 0;
for(int i=1; i<4; i++)
{
result.insert(path[i]+shift, ".");
shift++;
}
return result;
}
};