一、题目概述
二、思路方向
为了解决这个问题,我们可以使用回溯算法。回溯算法在这里非常适用,因为我们需要尝试在字符串中的不同位置插入点(
.
)来分割出可能的IP地址段,并且需要验证每个段是否满足条件(即,在0到255之间,且不以0开头但可以为0)。
三、代码实现
import java.util.ArrayList;
import java.util.List;
public class Solution {
public List<String> restoreIpAddresses(String s) {
List<String> result = new ArrayList<>();
List<String> segments = new ArrayList<>();
backtrack(s, segments, 0, result);
return result;
}
private void backtrack(String s, List<String> segments, int start, List<String> result) {
// 如果segments的数量达到了4,并且字符串s也完全遍历完了,那么这就是一个有效的IP地址
if (segments.size() == 4 && start == s.length()) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < segments.size(); i++) {
sb.append(segments.get(i));
if (i < segments.size() - 1) {
sb.append('.');
}
}
result.add(sb.toString());
return;
}
// 如果segments的数量已经等于4,但字符串s还没有遍历完,那么这是一个无效的组合,直接返回
if (segments.size() == 4) {
return;
}
// 尝试在当前位置开始的1, 2, 或3个字符(如果存在的话)作为一段IP地址
for (int len = 1; len <= 3 && start + len <= s.length(); len++) {
String segment = s.substring(start, start + len);
// 检查当前段是否是一个有效的IP地址段(0-255之间,且不以0开头但可以为0)
if (isValidSegment(segment)) {
segments.add(segment);
backtrack(s, segments, start + len, result);
segments.remove(segments.size() - 1); // 回溯
}
}
}
private boolean isValidSegment(String segment) {
// 如果以0开头但不是0本身,则无效
if (segment.startsWith("0") && segment.length() > 1) {
return false;
}
// 将字符串转换为整数并判断是否在0到255之间
int num = Integer.parseInt(segment);
return num >= 0 && num <= 255;
}
public static void main(String[] args) {
Solution solution = new Solution();
List<String> result = solution.restoreIpAddresses("25525511135");
System.out.println(result);
}
}
执行结果:
四、小结
上述代码首先定义了一个
restoreIpAddresses
方法,它初始化了一个结果列表result
,一个用来暂存当前IP地址段的列表segments
,并调用了一个backtrack
方法进行回溯。
backtrack
方法尝试在当前位置开始的1, 2, 或3个字符(如果存在的话)作为一段IP地址,并检查它是否有效。如果有效,就将其添加到segments
中,并递归调用backtrack
继续向后搜索。当找到有效的4段IP地址时,就将其组合成字符串并添加到结果列表中。最后,通过回溯(移除刚刚添加的段)来尝试其他可能的组合。
isValidSegment
方法用于检查一个字符串是否是一个有效的IP地址段。它首先检查是否以0开头但不是0本身(即不能以0开头后跟其他数字),然后将字符串转换为整数并检查是否在0到255之间。
结语
你的努力和坚持
总有一天会以你意想不到的方式回报你
!!!