法1:回溯
看了答案
想法:
- IP地址由4部分组成,四部分之间由 . 分隔,如:255.255.255.255(即11111111.11111111.11111111.11111111)
- 每部分>=0 && 每部分<= 255
- 每部分没有前导零
- 当前IP地址已经有4部分 && 输入的字符串已访问完最后一位,则当前IP地址是答案之一,存入
- 增加一个部分->继续寻找下一部分->找到所有可能的“下一部分”->删除之前衔接的一个部分(即给当前要删除部分的前一部分衔接其他可能部分的机会)
/** * @param {string} s * @return {string[]} */
var restoreIpAddresses = function(s) {
if(s.length == 0) {
return [];
}
var output = [];
doRestore(output, s, 1, "");
return output;
};
// output: 方便给结果集增加元素
// s: (剩余)输入串,每轮生成IP地址都需要
// k: 正在生成IP地址的第k部分(1, 2, 3, 4)
// partIP: 处于生成过程的IP地址,可能是结果之一function
doRestore(output, s, k, partIP) {
if(k == 5 || s.length == 0) { // 已经生成了4部分,或已经没有剩余的数字供分配
if(k == 5 && s.length == 0) { // 两者都满足才说明↓
output.push(partIP); // 此时的partIP为答案之一
}
// 如果:已经生成了4部分,但s仍有数字未分配;
// 或如果:s没有数字可分配了,但当前IP地址未生成
// 以上两者满足一个,直接返回
return;
}
var i = 0, part = "";
for(i = 0; i < s.length && i < 3; i++) {
if(i != 0 && s.charAt(0) == '0') {
// IP地址的每一部分没有前导零,若当前位置不是s的第一位,但却是0
// 则s的第一位0独占一部分,在该部分,不可能再衔接其他数字来组成新部分了
break;
}
part += s.charAt(i);
if(Number(part) <= 255) { // IP地址的每一部分 <= 255
if(partIP.length > 0) { // 第一部分前没有 .
part = '.' + part;
}
partIP += part;
doRestore(output, s.slice(i + 1), k + 1, partIP);
partIP = partIP.slice(0, partIP.length - part.length);
if(partIP.length > 0) { // 把之前加的.去掉
part = part.slice(1);
}
}
}
}
法2:暴力解法
在题解区看到的暴力解法Java写的,根据解法思想写了如下JavaScript版;这个解法绝了
/** * @param {string} s * @return {string[]} */
var restoreIpAddresses = function(s) {
if(s.length == 0) {
return [];
}
var output = [], temp = "";
var i = 0, j = 0, k = 0, l = 0;
var n1 = 0, n2 = 0, n3 = 0, n4 = 0;
for(i = 1; i < 4; i++) {
for(j = 1; j < 4; j++) {
for(k = 1; k < 4; k++) {
for(l = 1; l < 4; l++) {
if(i + j + k + l == s.length) {
n1 = Number(s.slice(0, i));
n2 = Number(s.slice(i, i + j));
n3 = Number(s.slice(i + j, i + j + k));
n4 = Number(s.slice(i + j + k));
if(n1 <= 255 && n2 <= 255 && n3 <= 255 && n4 <= 255) {
temp = "" + n1 + "." + n2 + "." + n3 + "." + n4;
if(temp.length == s.length + 3) {
output.push(temp);
}
}
}
temp = "";
}
}
}
}
return output;
};
个人认为这个解法的精妙之处在于利用了类型转换:字符串转换为数字之后,前导零会去除;将每部分数字与255比较之后,符合条件则用“.”衔接,再次比较生成的“IP地址”长度与[(原字符串长度)+3]。