题目:
有效 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
中的任何数字。你可以按 任何 顺序返回答案。
思路:
第一步:确定参数与返回值。参数为字符串s,起始下标startIndex,分隔符数量pointNum,无返回值
第二步:确定终止条件。当pointNum=3时,如果最后一段的字符串符合要求,则加入结果集
第三步:确定单层递归逻辑。for循环遍历字符串s,区间为[startIndex,s.length()-1]。如果区间[startIndex,i]的字符串是合法的,则在下标i的后面加上分隔符,即分割好一段合法的段。更新pointNum,递归字符串剩下的部分,回溯
代码:
List<String> result=new ArrayList<>();
public List<String> restoreIpAddresses(String s) {
backTracking(s,0,0);
return result;
}
public void backTracking(String s,int startIndex,int pointNum){
//已有三段,分割结束
if(pointNum==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)){
s=s.substring(0,i+1)+'.'+s.substring(i+1);
pointNum++;//记录'.'个数,
backTracking(s,i+2,pointNum);//插入'.'后,下一个字符串的位置在i+2
pointNum--;
s=s.substring(0,i+1)+s.substring(i+2);//回溯删掉'.'
}
else
break;
}
}
public boolean isValid(String s,int start,int end){
if(start>end)
return false;
//前导为0无效
if(s.charAt(start)=='0'&&start!=end)
return false;
int num=0;
for(int i=start;i<=end;i++){
if(s.charAt(i)>'9'||s.charAt(i)<'0')//非数字无效
return false;
num=num*10+(s.charAt(i)-'0');
if(num>255)//大于255无效
return false;
}
return true;
}