【问题描述】:
有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 ‘.’ 分隔。
例如:“0.1.2.201” 和 “192.168.1.1” 是 有效 IP 地址,但是 “0.011.255.245”、“192.168.1.312” 和 “[email protected]” 是 无效 IP 地址。
给定一个只包含数字的字符串 s ,用以表示一个 IP 地址,返回所有可能的有效 IP 地址,这些地址可以通过在 s 中插入 ‘.’ 来形成。你 不能 重新排序或删除 s 中的任何数字。你可以按 任何 顺序返回答案。
示例1:
输入:s = "25525511135"
输出:["255.255.11.135","255.255.111.35"]
实例2:
输入:s = "0000"
输出:["0.0.0.0"]
实例3:
输入:s = "101023"
输出:["1.0.10.23","1.0.102.3","10.1.0.23","10.10.2.3","101.0.2.3"]
【思路】:
回溯。用切割的思路。
例如:101023
第一种切法:1 dfs(01023) 。即把第一个作为一个字符串,然后后面的继续递归搜索。
第二种切法:10 dfs(1023) …
我们需要注意的几个点就是:所切下来的第一个字符串,它必须满足IP字符串的条件,即值在0—255之间。(然后注意不能有010, 020这种0开头的情况)。
如果它是IP字符串,那么我们才搜后面的。如果它已经不是了,那么它后面的也就没必要再搜了。
【代码】:
/**
* @param {string} s
* @return {string[]}
*/
var isIp = function(str){
//此处str.length >= 2,是为了防止有020, 01这种数字。很明显它们都是不合法IP
if(str.length >= 2 && str.charAt(0) == "0") return false;
var num = parseInt(str);
if(num >= 0 && num <= 255){
return true;
}
return false;
}
var dfs = function(arr, k, res, path){
//base case
if(path.length == 4 && k == arr.length){
res.push([...path].join("."));
return ;
}
if(path.length == 4) return ;
for(let end = k;end < arr.length;end++){
let str = "";
for(let j = k;j <= end;j++){
str += arr[j];
}
//判断当前字符串是否符合ip的规则
if(isIp(str)) {
//如果str是ip字符串,那么继续递归搜后面的
path.push(str);
dfs(arr, end + 1, res, path);
path.pop();
}else{
break;
}
}
}
var restoreIpAddresses = function(s) {
var arr = s.split("");
var res = [];
var path = [];
dfs(arr, 0, res, path);
return res;
};