File tree Expand file tree Collapse file tree 3 files changed +117
-0
lines changed
123. Restore IP Addresses Expand file tree Collapse file tree 3 files changed +117
-0
lines changed Original file line number Diff line number Diff line change 1+ 这道题的题意很好理解。
2+
3+ 给你一堆数字:
4+
5+ 25525511135
6+
7+ 让你分割成符合要求的形式:
8+
9+ 255.255.11.135
10+ 255.255.111.35
11+
12+
13+ 那么很自然的,首先考虑的是,什么叫符合要求。
14+
15+ IPV4的地址有以下几个特点:
16+
17+ 1 . 必须 4 段
18+ 2 . 每一段是 0 ~ 255 之间
19+
20+ 作为字符串,可能会出现 010 的情况,必须避免。故再加一条
21+
22+ 3 ) 长度大于 1 的子段,不能以 0 开头。
23+
24+ 可以看到,三条规定里,后两条都是针对分割后的每一段而言的。我们写一个函数来验证合法性:
25+
26+ ``` cpp
27+ bool valid (const string &s) {
28+ if (s.size() > 1 && s[ 0] == '0') return false;
29+ int num = std::stoi(s);
30+ return 0 <= num && num <= 255;
31+ }
32+ ```
33+
34+ 假定以下情况:
35+
36+ 255. | 25511135
37+ ^ ^
38+ ip origin string.
39+
40+ 在 0 ~ 255 中间,也意味着子段的长度只可能是 1、2、3,我们在试探的时候仅需试探三次,写成循环:
41+
42+ 255
43+ ^
44+ section: 2, 25, 255
45+
46+ 对于第一条,我们设定只能有 4 part, 每一次尝试都减 1.
47+
48+ ```cpp
49+ for (size_t i=1; i<4; ++i) {
50+ if (origin.size() < i) break; // 如果分了三段,最后一段不够长,stop
51+ string section = origin.substr(0, i); // 可能的子串
52+ if (valid(section)) {
53+ if (part != 1) section.append("."); // 除了最后一段,每一段后面用 `.` 分隔
54+ dfs(origin.substr(i), ip+section, part-1);
55+ }
56+
57+ }
58+ ```
59+
60+ 这明显是一个 DFS,那么递归必然有其退出条件。这里便是 ` part == 0 ` 的情况。
61+
62+ ``` cpp
63+ if (part == 0 ) {
64+ if (origin.empty()) ret.push_back(ip); // 最后一段,恰好分割完,入兜
65+ return; // 其他情况都不是我们想要的
66+ }
67+ ```
68+
69+ 总体来说,是比较简单的 DFS 方案。AC
Original file line number Diff line number Diff line change 1+ #include " solution.h"
2+ #include < iostream>
3+ using namespace std ;
4+
5+ int main ()
6+ {
7+ Solution s;
8+ vector<string> ips = s.restoreIpAddresses (" 25525511135" );
9+ for (const auto &ip : ips)
10+ cout << ip << endl;
11+ }
Original file line number Diff line number Diff line change 1+ #include < vector>
2+ using std::vector;
3+ #include < string>
4+ using std::string;
5+
6+ class Solution {
7+ vector<string> ret;
8+
9+ bool valid (const string &s) {
10+ if (s.size () > 1 && s[0 ] == ' 0' ) return false ;
11+ int num = std::stoi (s);
12+ return 0 <= num && num <= 255 ;
13+ }
14+
15+ void restore (const string &origin, const string &ip, int part)
16+ {
17+ if (part == 0 ) {
18+ if (origin.empty ()) ret.push_back (ip);
19+ return ;
20+ }
21+
22+ for (size_t i=1 ; i<4 ; ++i) {
23+ if (origin.size () < i) break ;
24+ string section = origin.substr (0 , i);
25+ if (valid (section)) {
26+ if (part != 1 ) section.append (" ." );
27+ restore (origin.substr (i), ip+section, part-1 );
28+ }
29+ }
30+ }
31+
32+ public:
33+ vector<string> restoreIpAddresses (string s) {
34+ if (s.size () >= 4 && s.size () <= 12 ) restore (s, " " , 4 );
35+ return ret;
36+ }
37+ };
You can’t perform that action at this time.
0 commit comments