给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。
示例:
输入: "25525511135"
输出: ["255.255.11.135", "255.255.111.35"]
解题思路:
寻找所有可能的IP地址。
1. 首先要明白IP地址的概念,4个数字,范围是[0-255]闭区间。
2. IP地址的4个数字中,除0以外,所有数字不能以0开头,这就意味着例如"255.001.02.04"这种情况是不允许出现的。
3. 一位数,两位数都可以全部存在,3位数不能超过255.如何判断三个字符能否可以构成IP中的数字,用这个定义即可:
#define is_IP3(x,y,z) (((x-'0')*100+(y-'0')*10+(z-'0'))<=255)
4. 严格意义上,这是个动态规划,因为存在递推关系。假设s(pos)为[pos,s.end())组成的字符串的IP种类,那么s(pos)=s(pos+1)+s(pos+2)+s(pos+3);计算s(pos+3)时意味着选取了3个字符,则需要判断3个字符能否构成IP数字,如果不能则无需递归。由于IP地址的长度是固定的,无需存储被访问过的DFS。
#define is_IP3(x,y,z) (((x-'0')*100+(y-'0')*10+(z-'0'))<=255) class Solution { public: vector<string> restoreIpAddresses(string s) { int_str = s; N = s.size(); DFS(0,0, ""); return res; } void DFS(int pos,int nums,string s) { if (nums == 4) { if (pos == N) { res.push_back(s); return ; } else return; } if (pos >= N) return; if (int_str[pos] == '0') { DFS(pos + 1, nums + 1, s+(nums == 0 ? "0" : ".0")); return; } //从当前位置起获取一个数字 //1位 string str = s + (nums == 0 ? "" : ".") + string(1,int_str[pos]); DFS(pos + 1,nums+1, s + (nums == 0 ? "" : ".") + string(1,int_str[pos])); //2位 if (pos + 1 <= N - 1) { DFS(pos + 2, nums + 1, s + (nums == 0 ? "" : ".") + string(1,int_str[pos])+ string(1,int_str[pos+1])); } //3位 if (pos + 2 <= N - 1&&is_IP3(int_str[pos], int_str[pos+1], int_str[pos+2])) { DFS(pos + 3, nums + 1, s + (nums == 0 ? "" : ".") + string(1, int_str[pos]) + string(1, int_str[pos + 1]) + string(1, int_str[pos + 2])); } } private: int N; string int_str; vector<string> res; }; |