NC20 数字字符串转化成IP地址
解法一: 暴力枚举
-
三层循环找三个
.
的位置 -
每一次循环判断前一段是否合法,不合法直接跳过当前层循环
-
最后一次循环判断第三段和第四段是否合法
-
最后将结果放入
ans
数组返回 -
可以AC,不推荐
/** * * @param s string字符串 * @return string字符串一维数组 */ function restoreIpAddresses( s ) { if(s.length <= 3) return [] let len = s.length - 1 let ans = [] function judge(start , end){ let numStr = s.split("").slice(start,end).join("") let num = Number(numStr) if((numStr.length > 1 && numStr[0] == '0') || num > 255 ){ return true } return numStr } for(let i = 1 ; i <= len - 2 ; i++){ if(judge(0 , i) === true) continue; for(let j = i + 1 ; j <= len - 1 ; j++){ if(judge(i , j) === true) continue for(let k = j + 1 ; k <= len ; k++){ if(judge(j , k) === true) continue if(judge(k , len + 1) === true) continue ans.push(judge(0 , i) + '.' + judge(i , j) + '.' + judge(j , k) + '.' + judge(k , len + 1)) } } } return ans } module.exports = { restoreIpAddresses : restoreIpAddresses };
解法二: dfs + 剪枝
- 当字符串
s
长度小于等于3的时候,直接返回[]
index
表示递归开始的下标,step
表示走到哪一步,也就是当前已经放置.
的数量each
表示当前递归生成的情况之一,ans
表示最终返回的结果- 当
step == 4
的时候,表示前面的三个.
都已经放好,判断最后一段是否合法,合法就push
进ans
数组,然后return
- 回溯后记得要把插入的
.
清除,step
也需要--
/**
*
* @param s string字符串
* @return string字符串一维数组
*/
function restoreIpAddresses( s ) {
if(s.length <= 3) return []
let ans = []
let each = s.split("")
function judge(start , end){
let numStr = s.split("").slice(start,end).join("")
let num = Number(numStr)
if((numStr.length > 1 && numStr[0] == '0') || num > 255 ){
return false
}
return true
}
function dfs (index , step){
if(step == 4){
if(judge(index , s.length) === true){
ans.push(each.join(""))
console.log(ans)
}
return;
}
for(let i = index + 1 ; i < s.length ; i ++){
if(judge(index , i) === true){
// 插入 "."
each.splice(i + step - 1 , 0 , ".")
step ++
dfs(i , step)
step --
each.splice(i + step - 1 , 1)
}else{
// 如果当前已经是非法情况或者大于255
// 再往后也只会不合法
// 所以直接结束这层循环
break
}
}
}
dfs(0 , 1)
return ans
}
module.exports = {
restoreIpAddresses : restoreIpAddresses
};