题目描述
给定一个只包含数字的字符串,用以表示一个 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 地址。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/restore-ip-addresses
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题目分析
这种有多少种可能的题目会需要dfs并回溯,回溯是指当走到尽头时,发现这条路走不通,便回到上个路口,尝试走另外一条路,如果再发现该节点所有路都走不通,或者是所有路都尝试过了,便再回到上个节点。
用二叉树来描述便是,若走到了叶子节点,发现没有子节点了,便回溯到上个父节点,再从这个父节点往另一个叶子节点搜索,若另外一个叶子节点不存在,或是另一个叶子节点已经被搜索过了,则再回到上个父节点,以此类推,直到遍历完整科树为止。
dfs框架
public void dfs() {
// 截止条件, 注意下文的dfs入参继续搜索条件与这里的返回条件相同时,便会触发返回。
if(返回条件) {
// 打印结果,或者是把结果挨个记录到输出数组中
return;
}
// 选择条件
for() {
// 操作数据
dfs(继续搜索条件)
// 还原被操作的数据
}
}
代码描述
class Solution {
List<String> list = new ArrayList<>();
Stack<String> stack = new Stack<>();
public List<String> restoreIpAddresses(String s) {
dfs(s, 0);
return list;
}
public void dfs(String s, int index) {
// 截止条件
if(index == s.length()|| stack.size() == 4) {
if(index == s.length() && stack.size() == 4) {
// 数组转字符串的api要记得
list.add(String.join(".", stack));
}
return;
}
// 选择条件
for(int i = 1; i <= 3; i++) {
if(index + i > s.length()) {
break;
}
String part = s.substring(index, index + i);
// 转整形的api要记得
if(Integer.parseInt(part) <= 255 && (part.equals("0") || part.charAt(0) != '0')) {
stack.push(part);
dfs(s, index + i);
stack.pop();
}
}
}
}
复杂度分析
时间复杂度: O(logN);