复原 IP 地址
难度:
标签:
题目描述
English description is not available for the problem. Please switch to Chinese.
代码结果
运行时间: 22 ms, 内存: 16.0 MB
/*
* 思路:
* 1. 使用stream流处理和组合字符串的所有可能分割。
* 2. 过滤掉无效的IP部分和长度不合适的组合。
*/
import java.util.List;
import java.util.ArrayList;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class SolutionStream {
public List<String> restoreIpAddresses(String s) {
return IntStream.rangeClosed(1, 3).boxed()
.flatMap(i -> IntStream.rangeClosed(1, 3).boxed()
.flatMap(j -> IntStream.rangeClosed(1, 3).boxed()
.flatMap(k -> IntStream.rangeClosed(1, 3).boxed()
.map(l -> new int[]{i, j, k, l}))))
.filter(parts -> parts[0] + parts[1] + parts[2] + parts[3] == s.length())
.map(parts -> new String[]{
s.substring(0, parts[0]),
s.substring(parts[0], parts[0] + parts[1]),
s.substring(parts[0] + parts[1], parts[0] + parts[1] + parts[2]),
s.substring(parts[0] + parts[1] + parts[2])
})
.filter(parts -> isValid(parts))
.map(parts -> String.join(".", parts))
.collect(Collectors.toList());
}
private boolean isValid(String[] parts) {
for (String part : parts) {
if (part.length() > 1 && part.startsWith("0")) return false;
int value = Integer.parseInt(part);
if (value < 0 || value > 255) return false;
}
return true;
}
}
解释
方法:
本题解使用了递归回溯的方法来构建所有可能的有效IP地址。从字符串的开始位置出发,通过递归地尝试每一个可能的分段(最长为3个字符),并且每段数字必须在0到255之间。特别地,单个'0'可以作为一段,但是'0'不能作为其他数字的前缀。在每一步递归中,如果当前的部分字符串符合IP地址的一个段的要求,就将其加到当前正在构建的IP地址中。当字符串被完全使用并且构建的IP地址由四段组成时,这个地址就被认为是一个有效的IP地址。通过这种方式,递归函数遍历所有可能的分段方式,直到找到所有的有效IP地址。
时间复杂度:
O(1)
空间复杂度:
O(n)
代码细节讲解
🦆
在递归回溯算法中,为什么选择使用字符串拼接来构建IP地址片段而不是使用数组或其他数据结构?
▷🦆
在处理以'0'开头的段时,为什么可以直接将'0'作为一个完整的段而不考虑后面的数字?
▷🦆
函数中递归的退出条件是基于已构建的IP地址段数多于4,这种设计是否能有效地减少不必要的递归调用?
▷