复制ip地址
给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。
示例:
输入: "25525511135"
输出: ["255.255.11.135", "255.255.111.35"]
思路( 99.2%):
这种给出所有组合的题目一般都是DFS+剪枝去解决,难点在于剪枝条件
剪枝条件:
- ip 地址长度
4<= len <= 12
- ip 地址分为4各部分
- ip 地址每段字符
1<= len <=3
- 如果段值为0,则段的长度只能为 1
- 每段的值范围:
[0,255]
public class RestoreIpAddresses {
int len;
public List<String> restoreIpAddresses(String s) {
if (s == null || s.length() <4 || s.length() > 12) {
return new ArrayList<>();
}
len = s.length();
List<String> res = new ArrayList<String>();
process(0, 0, s, new String[4], res);
return res;
}
// dfs 进行递归
public void process(int start, int seg, String s,String[] part, List<String> res) {
if (seg == 4) {
// 四段的总长度不等于总长,跳过
if (start != len) {
return;
}
// 添加结果 至 res中
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 3; i++) {
sb.append(part[i]).append('.');
}
sb.append(part[3]);
res.add(sb.toString());
return;
}
if (seg == 3 && s.length() - start > 3) {
return;
}
for (int i = 1; i <= 3; i++) {
// 如果超出最大长度则停止
if (start+i > len) {
break;
}
// 获取下一段的String
String segment = s.substring(start,start+i);
// 判断String是否合法
if(!valid(segment)) {
continue;
}
// 将该段放入part数组中
part[seg] = segment;
// 递归下一个状态
process(start+i, seg+1, s, part, res);
}
}
public boolean valid(String str) {
int val = Integer.valueOf(str);
// 该段值超出255 return false
if (val>255) {
return false;
}
// 首部为0 && 段长度超过1
if (str.charAt(0) == '0' && str.length() > 1) {
return false;
}
return true;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(new RestoreIpAddresses().restoreIpAddresses("19216801"));
}
}