复原IP地址
题目描述:
给定一个只包含数字的字符串,用以表示一个 IP 地址,返回所有可能从 s 获得的 有效 IP 地址 。你可以按任何顺序返回答案。有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 '.' 分隔。例如:"0.1.2.201" 和 "192.168.1.1" 是 有效 IP 地址,但是 "0.011.255.245"、"192.168.1.312" 和 "[email protected]" 是 无效 IP 地址。提示:0 <= s.length <= 3000s 仅由数字组成
示例
输入:s = "101023"输出:["1.0.10.23","1.0.102.3","10.1.0.23","10.10.2.3","101.0.2.3"]
class Solution {
private int len;
private List<String> result;
private String s;
public List<String> restoreIpAddresses(String s) {
// 初始化
this.len = s.length();
this.s = s;
this.result = new ArrayList<String>();
// 回溯算法
backtracking(0,0,"");
return this.result;
}
private void backtracking(int useLen,int symbol,String curStr){
if(symbol == 0 && (len < 4 || len > 12)) return;
if(symbol != 0 && (this.len-useLen > (4-symbol)*3 // 超过最大限制
|| this.len-useLen < 3-symbol+1)){
// 低于最小限制
return;
}
if(this.len == useLen){
this.result.add(curStr);
return;
}
if(symbol != 0) curStr += '.';
for(int i = useLen; i<useLen+3 && i<len ; i++){
String temp = this.s.substring(useLen,i+1);
int value = Integer.parseInt(temp);
if(value>255) break; // 处理大于255
if(temp.charAt(0) == '0' && temp.length()>1) break; // 处理非单个数的首位为零
backtracking(useLen+temp.length(),symbol+1,curStr+temp);
}
curStr = (symbol == 0)?curStr.substring(0,curStr.length()):curStr.substring(0,curStr.length()-1); // 还原
}
}
题意大概能反映出就是对回溯算法的应用,即具有"满足一定要求就可以继续深入执行下一步,否则退回到原先的上一步"的含义。
这里回溯方法的参数需要’.'符号的个数作为指标,也可以以使用的字符个数作为最终的结束条件(答案过滤)。每次我们还需要剪枝,即每个位置需要填的数字长度最少一个最多三个。我们对字符串s不断三个三个的遍历,最后可能因为不满足三个,则只需要将剩余的递归即可。考虑到题意的细节,要做相应的判断。详细请看代码,有疑问的欢迎留言。