题目:
有效 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 地址。
给定一个字符串 s,非数字的字符可替换为任意不包含在本字符串的数字,同样的字符只能替换为同样的数字,用以表示一个 IP 地址,返回所有可能的有效 IP 地址,这些地址可以通过在 s 中插入 '.' 来形成。你不能重新排序或删除 s 中的任何数字,你可以按任何顺序返回答案。
示例1:
输入:20212118136
输出:
20.212.118.136
202.12.118.136
202.121.18.136
202.121.181.36
示例2:
输入:11a2b22a037
输出:114.252.240.37
代码:回溯思想,利用map容器去重且使重复字符替换相同数字
import java.util.*;
public class ipCorrect {
static List<String> result=new ArrayList<>();//结果
static Map<Character,Character> map=new HashMap<>();//用来扫描ip是否有字母
static Character []chars={'0','1','2','3','4','5','6','7','8','9'};//扫描比对使用
static void backTracking(char []s,int startIndex,int pointNum){
if(pointNum==3){//点号数量3的时候结束
//判断第四段是否合法
if(isValid(s,startIndex,s.length-1)){
result.add(s);
}
return;
}
for (int i = startIndex; i < s.length; i++) {
if(isValid(s,startIndex,i)){ //判断 [startIndex,i] 这个区间的子串是否合法
StringBuilder sb=new StringBuilder(s.toString());
sb.insert(i+1,'.');//插入点号
pointNum++;
backTracking(sb.toString().toCharArray(),i+2,pointNum);// 插入点号后下一个子串的起始位置为i+2
pointNum--; //回溯
sb.deleteCharAt(i+1);//回溯删除点号
}else break;//条件不符合直接结束本次循环
}
}
static Boolean isValid(char []s,int start,int end){
if (start > end) {
return false;
}
if (s[start] == '0' && start != end) { // 不能以0开头
return false;
}
int num = 0;
for (int i = start; i <= end; i++) {
num = num * 10 + (s[i] - '0');
if (num > 255) { // 不能大于255
return false;
}
}
return true;
}
static List<String> restoreIpAddresses(char []s) {
dealEnglish(s);//处理英文
if (s.length > 12) return result; // 剪枝了
backTracking(s, 0, 0);
return result;
}
static void dealEnglish(char []s) {
for (int i = 0; i < s.length; i++) {//遍历一遍将数字存入map集合
if (s[i] <= '9' && s[i] >= '0'){
map.put(s[i],s[i]);
}
}
for (int i = 0; i < s.length; i++) {//再次遍历
if (s[i] > '9' || s[i] < '0') {//筛选字母部分
if(map.containsKey(s[i])){//如果map的key有对应的字符,说明之前以及存在了一个相同的数字要一样
s[i]=map.get(s[i]);//存在的话字母直接替换成对应的value
}
else{
for (int j = 0; j < chars.length; j++) {//不存在的话遍历chars,看有哪个数字没有用在ip上
if (!map.containsKey(chars[j])){//从0开始,遍历出map没有的数字
if(i==0){//防止字符串第一个为字母且其他数字未存在0情况
continue;
}
map.put(s[i],chars[j]);//放心map
s[i]=chars[j];//替换
break;
}
}
}
}
}
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
String s=sc.next();
restoreIpAddresses(s.toCharArray());
for (int i = 0; i < result.size(); i++) {
System.out.println(result.get(i));;
}
}
}