小小程序媛  
得之坦然,失之淡然,顺其自然,争其必然

题目

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集合;

下面用两种方法解决这个问题:

  1. 首先,一种简单的做法便是三重循环,得到构成ip地址的四段子地址,然后判断合法与否;该方法效率比较低;但是容易想到;
  2. 第二种方法,便是利用动态规划的思想;
    (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 };

 

GitHub测试程序源码

posted on 2015-12-22 15:39  Coding菌  阅读(153)  评论(0编辑  收藏  举报