思路
在做本题之前需要先了解一下回溯算法
另外在之前写了一篇博文:分割回文串与本题十分类似,可以先看了这题以后再来做本题
这里由于IP地址只能是四个部分组成的,所以最终我们发现path的数量超过4的时候就不是合法的,当path的数量为4并且当前已经遍历完了s中的所有元素的时候,说明path是满足条件的,所以收集答案到结果集result中
合法性校验
这里的path中的所有元素一定都是满足结果条件的,因为在放入path之前有对其的合法性进行校验,这里单独写了一个isValid函数来校验每个子串是否是合法的,如果子串的长度大于1并且是以0开头,那么不合法,如果把子串是 > 255的也不合法,其余情况是合法的
当遍历的过程中如果遇到是不合法的话我们就return,说明后续再继续切割也是不合法的,比如s = “25525511135”,当切割的第一个子串是str = '2552’时,这个子串已经是不合法的,就不需要继续往后遍历来切割,如果再网下一个位置去切割,str = '25525’仍然是不合法的,所以到这里需要停止,使用return
,这里跟之前的分割回文串
不同,因为假设分割回文串的str = ‘ab’,下一个str后加了一个数之后可能是"aba",这样又能形成回文串,所以不满足的时候使用continue,但是数字已经不满足条件以后再往后加数字越变越大更是不会合法的
实现
var restoreIpAddresses = function (s) {
let result = [], path = [];
const backtracking = (s, startIndex) => {
if (path.length > 4) return;
if (startIndex === s.length && path.length === 4) {
result.push(path.join('.'))
return;
}
for (let i = startIndex; i < s.length; i++) {
const str = s.slice(startIndex, i + 1)
if (isValid(str)) {
path.push(str)
} else {
return;
}
backtracking(s, i + 1);
path.pop();
}
}
backtracking(s, 0)
return result;
};
// 判断是否有效值
const isValid = (str) => {
if (str.length > 1 && str[0] === '0') return false;
if (Number(str) > 255) return false;
return true;
}