描述
现在有一个只包含数字的字符串,将该字符串转化成IP地址的形式,返回所有可能的情况。
例如:
给出的字符串为"25525522135",
返回[“255.255.22.135”, “255.255.221.35”]. (顺序没有关系)
实现思路
这道题应该使用回溯法求解,因为每一层可以由上一层结果+ 子问题的结果组成,我们可以设置一个len作为执行的进度,然后基于这个len进度,向前推移的步长尾i,在循环里判断substring(len,i)是不是符合条件的,加入到预备结果集中
注意有几个情况是需要跳出循环并且重新计算的:
- 起点的ip第一个.前的数字不能为0
- 每个ip内段的长度为1——3,不能超过3,并且字符串转换为Integer的大小不能超过255
- 必须有四个这样的数,多于或者少于都不能算是结果
根据上面的条件,可以整理出如下的代码:
public static List<String> ipAddressSplit(String str){
/**
* 如果队列是空,直接返回
*/
if (str == null || str.length() ==0) {
return Collections.emptyList();
}
int len = 0;
List<String> result = new ArrayList<>();
dfs(new ArrayList<>(),len, str,result);
return result;
}
//加入到结果集的函数需要满足两个条件: 1. 结果集大小等于4 2. 长度计量len 等于字符串长度 (没有多余的字符)
private static void dfs(List<String> resultIp, int len, String str, List<String> result) {
if (resultIp.size() > 4) {
return;
}
if( resultIp.size() == 4 && len == str.length()){
result.add(constructIp(resultIp));
}
//如果小于4,开始回溯
for (int i=len+1; i<= str.length() && i <= len + 3; i++) {
String strTemp = str.substring(len, i);
int value = Integer.parseInt(strTemp);
if (str.charAt(len) == '0' && strTemp.length() > 1) {
break;
}
//如果处于0 -255之间,则继续修改len为i的标识,继续递归
if (value <= 255 && value >=0) {
resultIp.add(strTemp);
//从下一个位置i开始回溯
dfs(resultIp, i, str, result);
//回溯完当前这种情况,记得退后一步,e.g. 255.255.223.5 ---> 255.255.223.
resultIp.remove(resultIp.size() -1);
}
}
}
private static String constructIp(List<String> resultIp) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(resultIp.get(0));
for(int k=1 ; k< resultIp.size(); k++){
stringBuilder.append(".").append(resultIp.get(k));
}
return stringBuilder.toString();
}
使用测试字符串“25525522135”运行,结果有两个: