Description
Given a string containing only digits, restore it by returning all possible valid IP address combinations.
Example:
Input:
"25525511135"
Output:
["255.255.11.135", "255.255.111.35"]
分析
题目的意思是:给定由数字组成的字符串,返回所有可能形式的ip地址
-
一是只要遇到字符串的子序列或配准问题首先考虑动态规划DP,二是只要遇到需要求出所有可能情况首先考虑用递归。
-
这道题并非是求字符串的子序列或配准问题,更符合第二种情况,所以我们要用递归来解。我们用k来表示当前还需要分的段数,如果k = 0,则表示三个点已经加入完成,四段已经形成,若这时字符串刚好为空,则将当前分好的结果保存。若k != 0, 则对于每一段,我们分别用一位,两位,三位来尝试,分别判断其合不合法,如果合法,则调用递归继续分剩下的字符串,最终和求出所有合法组合
C++实现
class Solution {
public:
vector<string> restoreIpAddresses(string s) {
vector<string> res;
string out="";
solve(s,4,out,res);
return res;
}
void solve(string s,int k,string out,vector<string> &res){
if(k==0){
if(s.empty()){
res.push_back(out);
}
return ;
}
for(int i=1;i<4;i++){
if(s.size()>=i&&isValid(s.substr(0,i))){
if(k==1) solve(s.substr(i),k-1,out+s.substr(0,i),res);
else solve(s.substr(i),k-1,out+s.substr(0,i)+'.',res);
}
}
}
bool isValid(string s){
if(s.empty()||s.size()>3||(s.size()>1&&s[0]=='0')){
return false;
}
int res=atoi(s.c_str());
return res<=255&&res>=0;
}
};
Python实习那
我用python实现了一个递归版本,在牛课网上ac了,调了好久,这里给了我一个启发,不管自己的代码写得再烂,都要自己一步一步的改出来,这样才有提升
- 主要思想是用cur记录遍历字符串的起始位置
- 符合条件的字符串加入到ans list中,符合ip条件的ans加入到res集合中
- 递归的条件是当前截取的字符串符合0~255的区间内,ans加入当前的字符串,回溯的时候记得把当前的值弹出来就行
class Solution:
def solve(self, s,ans, res, start):
if start == len(s):
if len(ans)==4:
res.append('.'.join(ans[:]))
return
if len(ans)>4:
return
if s[start]=='0':
ans.append(s[start])
self.solve(s,ans,res,start+1)
ans.pop()
else:
for i in range(start,len(s)):
ip = s[start:i+1]
if 0<=int(ip)<=255:
ans.append(ip)
self.solve(s,ans,res,i+1)
ans.pop()
def restoreIpAddresses(self, s: str) -> List[str]:
res = []
self.solve(s,[],res,0)
return res
参考文献
[编程题]restore-ip-addresses
[LeetCode] Restore IP Addresses 复原IP地址