题目描述
有效 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:
输入: s = "25525511135"
输出: ["255.255.11.135","255.255.111.35"]
分析题意
无效的IP地址:
- IP地址
超过四段 - IP地址的每段长度
超过3位数 - IP地址每段的
第一个数为0,后面两位或一位不为0,例如:01,011等 - IP地址
每段>255
思路
- 对于切割问题,首先想到:
回溯算法,先抽象为树形结构
-
回溯算法:终止条件: path.length==4&&startIndex==s.length(表示:IP地址为4段并且此时s字符串已经全部遍历完成)- 传参:s(字符串),startIndex:(表示每次从何处开始切割)
- 单层递归逻辑:
for(let i=startIndex;i<s.length;i++){ //判断是否合法 if(isVaild(s,startIndex,i)){ //添加合法路径 path.push(s.slice(startIndex,i+1)); // 递归下一次切割 backTracking(s,i+1); // 回溯操作 path.pop(); }else{ continue } }
完整代码
function restoreIpAddresses(s: string): string[] {
let result=[],path=[];
//递归方法
function backTracking(s:string,startIndex:number):void{
//终止条件
if(path.length==4&&startIndex==s.length){
result.push(path.join("."));
return;
}
//单层递归
for(let i=startIndex;i<s.length;i++){
if(isVaild(s,startIndex,i)){
path.push(s.slice(startIndex,i+1));
backTracking(s,i+1);
path.pop();
}else{
continue
}
}
}
//判断数字是否合法
function isVaild(s:string,start:number,end:number):boolean{
let news=s.slice(start,end+1);
if(news.length > 3 || +news > 255) return false;
if(news.length > 1 && news[0] === "0") return false;
return true
}
backTracking(s,0);
return result;
};
总结
本题与切割回文串思路类似,遇到组合,切割等问题时,优先考虑回溯算法,将其抽象为一个树形结构,可以使我们更好的理解。