题目
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)
思路
这个题目就和 Palindrome Partitioning 很像了,而且比那个的DFS的递归要简单一些,让常人更好理解一些。但是边界条件更多,要考虑清楚。
整体思路就是深度优先搜索,首先看到边界条件没,如果没有,就深度搜索:
一开始搜索1个字符和剩下的字符串,判断该字符的index是否越界了,对于剩下的字符串递归;
然后是2个字符和剩下的字符串,判断这2个字符的首字符是否是0,对于剩下的字符串递归;
然后是3个字符和剩下的字符串,判断这3个字符的首字符是否是0,并且这3个字符组成的数字是否小于等于255,对于剩下的字符串递归。
根据 IP 地址的规则,将字符串划分成有效的 IP 地址。
样的 IP 地址都是无效的:"0.1.0.010","0.1.00.10" ,所以代码中用 if(a=='0') return ; 将其踢除。
class Solution {
public:
vector<string> restoreIpAddresses(string s) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
vector<string> result;
string str="";
myRestoreIP(result, s, str, 0, 0);
return result ;
}
void myRestoreIP(vector<string> &result, string &S, string str, int cur, int num) {
if(cur>=S.length()){
if(num==4) {
str.erase(str.end()-1);
result.push_back(str);
}
return ;
}
if(num>4) return ;
char a = S[cur];
myRestoreIP(result,S,str+a+'.',cur+1,num+1);
if(cur+1==S.length())
return ;
char b = S[cur+1];
if(a=='0') return ;
myRestoreIP(result,S,str+a+b+'.',cur+2,num+1);
if(cur+2==S.length())
return ;
char c = S[cur+2];
int val = 100*(a-'0')+10*(b-'0')+c-'0';
if(val>255)
return ;
myRestoreIP(result,S,str+a+b+c+'.',cur+3,num+1);
}
};
查看了网上其他的代码,发现本人的代码是最简洁的。
--------------------------------------------------------------------------------------------------------------
另外,也可以往原始字符串中插入 '.' 来生成结果 , 具体可参考 链接
class Solution {
//DFS
//Note: there are 4 special process here
public:
void DFS(int curStep, int curPos, const string& s, string& curAns, vector<string>& ans)
{
if(s.size()-curPos > (5-curStep)*3)//3. cut off, for the long number
return;
if(curPos >= s.size()) return;//4. check if it is valid
if(curStep == 4)
{
if( IsValid(curPos, s.size()-1, s) )
ans.push_back(curAns);
}
for (int i = curPos; i < s.size(); ++i)
{
if ( IsValid(curPos, i, s) )
{
curAns.insert(curAns.begin()+i+curStep, '.');
DFS(curStep+1, i+1, s, curAns, ans);
curAns.erase(curAns.begin()+i+curStep);
}
}
}
bool IsValid( int start, int end, const string& s )
{
if(s[start] == '0' && end != start)//1. 001 is not valid
return false;
if(end-start > 3)//2. len greater than 3 is also not valid, too long may cause overflow
return false;
int res = 0;
for (int i = start; i <= end; ++i)
res = res*10+s[i]-'0';
if(res <= 255)
return true;
}
vector<string> restoreIpAddresses(string s) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
vector<string> ans;
string curAns = s;
DFS(1, 0, s, curAns, ans);
return ans;
}
};