Skip to content

Commit efaf672

Browse files
committed
复原IP地址
1 parent 572c45b commit efaf672

File tree

1 file changed

+139
-0
lines changed

1 file changed

+139
-0
lines changed
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
package com.leetcode_cn.medium;
2+
3+
import java.util.ArrayList;
4+
import java.util.LinkedList;
5+
import java.util.List;
6+
7+
/*****************复原IP地址************/
8+
/**
9+
* 给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。
10+
*
11+
* 示例:
12+
*
13+
* 输入: "25525511135"
14+
*
15+
* 输出: ["255.255.11.135", "255.255.111.35"]
16+
*
17+
* @author ffj
18+
*
19+
*/
20+
public class RestoreIPAddresses {
21+
22+
// 数字长度
23+
int n;
24+
// 数字
25+
String s;
26+
// 存储三段数字
27+
LinkedList<String> segments = new LinkedList<String>();
28+
// 存储结果
29+
ArrayList<String> output = new ArrayList<String>();
30+
31+
public List<String> restoreIpAddresses(String s) {
32+
n = s.length();
33+
this.s = s;
34+
backtrack(-1, 3);
35+
return output;
36+
}
37+
38+
/**
39+
* 校验数字是否合理
40+
*
41+
* @param segment
42+
* @return
43+
*/
44+
public boolean valid(String segment) {
45+
/*
46+
* Check if the current segment is valid : 1. less or equal to 255 2. the first
47+
* character could be '0' only if the segment is equal to '0'
48+
*/
49+
int m = segment.length();
50+
if (m > 3)
51+
return false;
52+
return (segment.charAt(0) != '0') ? (Integer.valueOf(segment) <= 255) : (m == 1);
53+
}
54+
55+
/**
56+
* 分为三段
57+
*
58+
* @param curr_pos
59+
*/
60+
public void update_output(int curr_pos) {
61+
/*
62+
* Append the current list of segments to the list of solutions
63+
*/
64+
String segment = s.substring(curr_pos + 1, n);
65+
if (valid(segment)) {
66+
segments.add(segment);
67+
// 三段拼接
68+
output.add(String.join(".", segments));
69+
// 回溯
70+
segments.removeLast();
71+
}
72+
}
73+
74+
/**
75+
* 回溯法 一段一段截
76+
*
77+
* @param prev_pos
78+
* 截取起始点
79+
* @param dots
80+
* 剩余段数
81+
*/
82+
public void backtrack(int prev_pos, int dots) {
83+
/*
84+
* prev_pos : the position of the previously placed dot dots : number of dots to
85+
* place
86+
*/
87+
// The current dot curr_pos could be placed
88+
// in a range from prev_pos + 1 to prev_pos + 4.
89+
// The dot couldn't be placed
90+
// after the last character in the string.
91+
int max_pos = Math.min(n - 1, prev_pos + 4);
92+
for (int curr_pos = prev_pos + 1; curr_pos < max_pos; curr_pos++) {
93+
String segment = s.substring(prev_pos + 1, curr_pos + 1);
94+
if (valid(segment)) {
95+
segments.add(segment); // place dot
96+
if (dots - 1 == 0) // if all 3 dots are placed
97+
update_output(curr_pos); // add the solution to output
98+
else
99+
backtrack(curr_pos, dots - 1); // continue to place dots
100+
segments.removeLast(); // remove the last placed dot
101+
}
102+
}
103+
}
104+
105+
/**
106+
* 讨论中解法
107+
*
108+
* 3-loop divides the string s into 4 substring: s1, s2, s3, s4. Check if each
109+
* substring is valid. In isValid, strings whose length greater than 3 or equals
110+
* to 0 is not valid; or if the string's length is longer than 1 and the first
111+
* letter is '0' then it's invalid; or the string whose integer representation
112+
* greater than 255 is invalid.
113+
*
114+
* @param s
115+
* @return
116+
*/
117+
public List<String> restoreIpAddresses1(String s) {
118+
List<String> res = new ArrayList<String>();
119+
int len = s.length();
120+
for (int i = 1; i < 4 && i < len - 2; i++) {
121+
for (int j = i + 1; j < i + 4 && j < len - 1; j++) {
122+
for (int k = j + 1; k < j + 4 && k < len; k++) {
123+
String s1 = s.substring(0, i), s2 = s.substring(i, j), s3 = s.substring(j, k),
124+
s4 = s.substring(k, len);
125+
if (isValid(s1) && isValid(s2) && isValid(s3) && isValid(s4)) {
126+
res.add(s1 + "." + s2 + "." + s3 + "." + s4);
127+
}
128+
}
129+
}
130+
}
131+
return res;
132+
}
133+
134+
public boolean isValid(String s) {
135+
if (s.length() > 3 || s.length() == 0 || (s.charAt(0) == '0' && s.length() > 1) || Integer.parseInt(s) > 255)
136+
return false;
137+
return true;
138+
}
139+
}

0 commit comments

Comments
 (0)