# 原地址
https://leetcode-cn.com/problems/restore-ip-addresses/
# 题目
给定一个只包含数字的字符串,用以表示一个 IP 地址,返回所有可能从 s 获得的 有效 IP 地址 。你可以按任何顺序返回答案。
有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 '.' 分隔。
例如:"0.1.2.201" 和 "192.168.1.1" 是 有效 IP 地址,但是 "0.011.255.245"、"192.168.1.312" 和 "192.168@1.1" 是 无效 IP 地址。
示例 1:
输入:s = "25525511135"
输出:["255.255.11.135","255.255.111.35"]
示例 2:
输入:s = "0000"
输出:["0.0.0.0"]
# 分析
- 暴力法:我是通过四次循环嵌套,完成的验证,应该是最笨的方法
- 官方:回溯,区别也是用了递归,和暴力差别不大。
# 代码
```java
class Solution {
public List<String> restoreIpAddresses(String s) {
List list = new ArrayList();
for (int i = 1; i <= 3 && i <= s.length(); i++) {
String a = s.substring(0, i);
if (valid(a)) {
for (int j = 1; j <= 3 && i + j <= s.length(); j++) {
String b = s.substring(i, i + j);
if (valid(b)) {
for (int k = 1; k <= 3 && i + j + k <= s.length(); k++) {
String c = s.substring(i + j, i + j + k);
if (valid(c)) {
String d = s.substring(i + j + k);
if (valid(d)) {
list.add(a + "." + b + "." + c + "." + d);
}
} else {
break;
}
}
} else {
break;
}
}
} else {
break;
}
}
return list;
}
public boolean valid(String s) {
if (s.length() == 0) {
return false;
}
if (s.length() > 1 && s.charAt(0) == '0') {
return false;
}
if (s.length() > 3) {
return false;
}
int num = Integer.parseInt(s);
if (num <= 255) {
return true;
} else {
return false;
}
}
}
```
# 官方代码
```java
class Solution {
public List<String> restoreIpAddresses(String s) {
int len = s.length();
List<String> res = new ArrayList<>();
if (len > 12 || len < 4) {
return res;
}
Deque<String> path = new ArrayDeque<>(4);
dfs(s, len, 0, 4, path, res);
return res;
}
// 需要一个变量记录剩余多少段还没被分割
private void dfs(String s, int len, int begin, int residue, Deque<String> path, List<String> res) {
if (begin == len) {
if (residue == 0) {
res.add(String.join(".", path));
}
return;
}
for (int i = begin; i < begin + 3; i++) {
if (i >= len) {
break;
}
if (residue * 3 < len - i) {
continue;
}
if (judgeIpSegment(s, begin, i)) {
String currentIpSegment = s.substring(begin, i + 1);
path.addLast(currentIpSegment);
dfs(s, len, i + 1, residue - 1, path, res);
path.removeLast();
}
}
}
private boolean judgeIpSegment(String s, int left, int right) {
int len = right - left + 1;
if (len > 1 && s.charAt(left) == '0') {
return false;
}
int res = 0;
while (left <= right) {
res = res * 10 + s.charAt(left) - '0';
left++;
}
return res >= 0 && res <= 255;
}
}
```

93. 复原 IP 地址