题目
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)
分析
给定一个字符串,给出其可构成的所有ip集合;
下面用两种方法解决这个问题:
- 首先,一种简单的做法便是三重循环,得到构成ip地址的四段子地址,然后判断合法与否;该方法效率比较低;但是容易想到;
- 第二种方法,便是利用动态规划的思想;
(1)对于给定的字符串,IP地址要分隔为4段,第一段有最多三种可能2、 25 、 255因为其最长只能为3个字符;
(2)此时若我们划分的第一段为合法的,我们可以递归将剩余子串划分为3段;将ip1与集合中所有合法后三段ip链接即可;
(3)明显的,利用以上理念很容易写出递归实现代码;
AC代码
1 class Solution { 2 public: 3 /*方法一:动态规划方式*/ 4 vector<string> restoreIpAddresses(string s) { 5 if (s.empty()) 6 return vector<string>(); 7 8 return getIpAddresses(s, 4); 9 } 10 11 /*s为需要划分的字符串,num为需要划分段数*/ 12 vector<string> getIpAddresses(string s, int num) 13 { 14 int len = s.length(); 15 if (s.empty() || num <= 0 || len > 3 * num || len < num) 16 return vector<string>(); 17 vector<string> ips; 18 if (num == 1) 19 { 20 if (isLegal(s)) 21 ips.push_back(s); 22 return ips; 23 }//if 24 else{ 25 //得到首段,每段ip长度不超过3 26 for (int i = 0; i < len && i < 3; ++i) 27 { 28 string ip1 = s.substr(0, i + 1); 29 if (isLegal(ip1)) 30 { 31 vector<string> tmpIps = getIpAddresses(s.substr(i + 1), num - 1); 32 if (!tmpIps.empty()) 33 { 34 auto iter = tmpIps.begin(); 35 while (iter != tmpIps.end()) 36 { 37 string ip = ip1 + "." + *iter; 38 ips.push_back(ip); 39 ++iter; 40 }//while 41 }//if 42 }//if 43 }//for 44 return ips; 45 } 46 } 47 48 /*判断ip段是否合法*/ 49 bool isLegal(string ip) 50 { 51 if (ip.empty()) 52 return false; 53 else if (ip[0] == '0') 54 return ip.length() == 1; 55 else{ 56 int pos = ip.length() - 1; 57 int sum = 0 , tmp = 1; 58 while (pos >= 0) 59 { 60 sum = sum + (ip[pos] - '0') * tmp; 61 if (sum > 255) 62 return false; 63 tmp *= 10; 64 --pos; 65 }//while 66 }//else 67 return true; 68 } 69 70 /*方法二:三重循环,效率低*/ 71 vector<string> restoreIpAddresses2(string s) { 72 vector<string> ips; 73 if (s.empty()) 74 return vector<string>(); 75 76 int len = s.length(); 77 for (int i = 0; i < len - 2; ++i) 78 { 79 for (int j = i + 1; j < len - 1; ++j) 80 { 81 for (int k = j + 1; k < len; ++k) 82 { 83 string ip1 = s.substr(0, i + 1); 84 string ip2 = s.substr(i + 1, j - i); 85 string ip3 = s.substr(j + 1, k - j); 86 string ip4 = s.substr(k + 1); 87 if (isLegal(ip1) && isLegal(ip2) && isLegal(ip3) && isLegal(ip4)) 88 ips.push_back(ip1 + "." + ip2 + "." + ip3 + "." + ip4); 89 }//for 90 }//for 91 }//for 92 93 return ips; 94 } 95 };