1. 问题描述:
给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。
示例:
输入: "25525511135"
输出: ["255.255.11.135", "255.255.111.35"]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/restore-ip-addresses
2. 思路分析:
① 题目其实比较好理解,对于构成IP地址,我们可以对当前的字符串的当前位置截取一个字符,或者是两个字符,或者是三个字符来尝试不同的组合方案,考虑到尝试不同的可能性那么可以考虑使用递归来求解,这个也是可以使用递归求解的特点,可以尝试所有的可能性,对于每一次递归到当前的位置都是使用上面三种的可能的尝试方案去尝试,所以自然对应着三个平行的状态,对于三个递归方法
② 合理的IP地址使用点.来分割的四个数字来组成的,并且不能够存在前导的0,一开始的时候没有注意到前导0所以提交上去部分答案错误,对于截取一位字符不需要注意是否存在前导0,因为一位字符是可以使用0构成的,而对于截取的两位数字与三位数字那么需要判断截取的字符串中的第一位是否是0假如不是0那么可以继续递归下去,因为递归的时候最大的ip地址的没有点的情况下的长度是12,所以当字符串长度超过12明显是无论怎么样组合都是无法构成合理的IP的,直接返回即可,所以当字符串长度小于等于12才进行递归所以不会超时
③我们在写代码的时候最好先弄好简单的例子的逻辑,比如在尝试上面三种截取字符方案的时候会涉及到边界的问题,而这个时候使用简单的数据那么就相对比较好测试,容易找到问题出现在哪里,比如先尝试字符串为1234的情况,这样更容易找出边界上的错误,并且递归方法中需要什么参数那么后面在写的时候可以动态进行添加上去,一开始的时候不用考虑这么全面
3. 代码如下:
class Solution {
List<String> res = new ArrayList<>();
public List<String> restoreIpAddresses(String s) {
if (s.length() > 12) return new ArrayList<>();
/*第二个参数表示的是递归到字符串的第几个位置了, 最后一个参数用来统计出现当出现四个数字的时候pos位置是否在字符串的最末尾这样用来判断是否得到的是合法的ip地址*/
dfs(s, 0, "", 0);
return res;
}
/*可以知道存在三个平行状态*/
private void dfs(String s, int pos, String cur, int count) {
if (pos == s.length() && count == 4){
/*合法的IP地址*/
res.add(cur.substring(0, cur.length() - 1));
return;
}
if (pos > s.length() || count > 4) return;
if (pos + 1 <= s.length()){
String t = s.substring(pos, pos + 1);
dfs(s, pos + 1, cur + t + ".", count + 1);
}
if (pos + 2 <= s.length()){
String t = s.substring(pos, pos + 2);
dfs(s, pos + 2, cur + t + ".", count + 1);
}
if (pos + 3 <= s.length()){
/*注意当超过三位数的时候需要判断截取的数字不能够超过255*/
String t = s.substring(pos, pos + 3);
if (Integer.parseInt(t) <= 255) {
dfs(s, pos + 3, cur + t + ".", count + 1);
}
}
}
}