「这是我参与11月更文挑战的第15天,活动详情查看:2021最后一次更文挑战」
前言
力扣第九十三题 复原 IP 地址 如下所示:
给定一个只包含数字的字符串 s ,用以表示一个 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"]
示例 3:
输入: s = "1111"
输出: ["1.1.1.1"]
一、思路
题目简单翻译以下就是:正确分割字符串,保证分割的结果为有效的IP,返回所有可能的结果
有效IP地址有两个要求:
- 不能含有前导
0(如192.168.2.01) - 四个整数的范围都为
0 ~ 255
这一题很明显就是使用递归来实现的,我们可以模拟分割字符串这个过程。正好可以利用题目中的要求进行有效的剪枝。
那么递归的方法要做什么事情呢?
其实也很简单,递归要做的就是:一个一个的分割字符串,直到获得正确的结果。伪代码如下所示:
public void dfs(String str, List<String> curRet, int begin) {
if (begin == str.length() && curRet.size() == 4) {
// 添加结果
ans.add(String.join(".", curRet));
return;
}
for (int i=begin; i<str.length(); i++) {
if (Integer.parseInt(str.substring(begin, i+1)) > 255)
break;
curRet.add(str.substring(begin, i+1));
dfs(str, curRet, i+1);
curRet.remove(curRet.size()-1);
}
}
如上面的伪代码所:如果当前分割出来的字符串大于 255,我们直接退出当前层循环,回到上一层即可。(剪枝)
在实现的过程中,我们要考虑到一些边界情况,以便于获得争取的结果集合和剪枝
- 如果碰到了前导
0,则当前层的分割结果只能为0(前导0是指某一层分割时,第一个字符串就是0,如010010分割时,只能让第一个0单独一组) - 我们发现还有一种情况也可以剪枝,当临时结果集中已有三个了,但字符串剩下的长度大于等于
4时,我们也没必要再向下递归了。(如处理25525511135时,前三个分割的结果为[2,5,5],就没必要再去分割第四个结果了,因为无论如何也不可能小于255)
二、实现
实现代码
实现代码与思路中保持一致,我们在处理一些边界情况时,要特别的注意。
List<String> ans = new ArrayList<>();
public List<String> restoreIpAddresses(String s) {
dfs(s, new ArrayList<>(), 0);
return ans;
}
public void dfs(String str, List<String> curRet, int begin) {
if (begin == str.length() && curRet.size() == 4) {
// 添加结果
ans.add(String.join(".", curRet));
return;
}
if (curRet.size() == 3 && str.length() - begin > 3) { // 如剩余的字符大于3,则剪枝
return;
}
for (int i=begin; i<str.length(); i++) {
if (i == begin && str.charAt(i) == '0') {
curRet.add("0");
dfs(str, curRet, begin+1);
curRet.remove(curRet.size()-1);
break;
}
String temp = str.substring(begin, i+1);
int val = Integer.parseInt(temp);
if (val > 255)
break;
curRet.add(temp);
dfs(str, curRet, i+1);
curRet.remove(curRet.size()-1);
}
}
测试代码
public static void main(String[] args) {
String s = "";
String s1 = "010010";
new Number93().restoreIpAddresses(s1);
}
结果
三、总结
感谢看到最后,非常荣幸能够帮助到你~♥
如果你觉得我写的还不错的话,不妨给我点个赞吧!如有疑问,也可评论区见~