93. 复原 IP 地址
有效 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 中的任何数字。你可以按 任何 顺序返回答案。
解:
- 目标就是把字符串分成四份,并且不含有前导零并且小于等于255
- 递归函数的参数含义为,idx:当前在第几个字符,num:当前是第几份,preStr:idx之前的字符切分情况
- 从第0个字符,第0份开始递归
- 对每一份来说,可以选1 ~ 3个字符,遍历1 ~ 3,截取从idx开始往后的字符,排除前导0和大于255的情况,把截取的字符拼接到preStr后,往下一份去递归,递归结束后将preStr重置为拼接前的值
- 当来到第4份时,同时也没有剩余字符,说明这是一组正确的解,放入结果数组中
const restoreIpAddresses = function(s) {
const res = []
// idx: 当前在第几个字符 num:当前是第几个.
function getRes(idx, num, preStr) {
// num越界并且idx刚好走完,表明这是一种成功的结果
if (num === 4) {
if (idx === s.length) {
res.push(preStr)
}
return
}
// 记录preStr,递归完回溯
const tempStr = preStr
for (let i = 1; i < 4; i++) {
const str = s.substr(idx, i)
// 排除前导0和大于255的情况
if (!(str.length > 1 && str[0] === '0') && +str <= 255) {
preStr += num === 3 ? str : str + '.'
getRes(idx + i, num + 1, preStr)
preStr = tempStr
}
}
}
getRes(0, 0, '')
return res
};