持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第10天,点击查看活动详情
说明:文章部分内容及图片出自网络,如有侵权请与我本人联系(主页有公众号:小攻城狮学前端)
作者:小只前端攻城狮、 主页:小只前端攻城狮的主页、 来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
【LeetCode 93. 复原 IP 地址 】- JavaScript(回溯+剪枝)
题目描述
有效 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 中的任何数字。你可以按 任何 顺序返回答案。
示例 1:
输入:s = "25525511135" 输出:["255.255.11.135","255.255.111.35"]
回溯
思路分析:
整体的的思路:分析题目就知道这是一个标准的回溯,大致思路利用一个变量pos标识是否字符串都用上了。因为ip是0到255,4个段位组成,而且必须把字符串数字用完。 问题的难点是如何拆分ip的地址段,也是剪枝的难点。每一段的位数在1~3位,值域在0~255范围,段数为4个。具体注意点:
回溯过程中如果查找的位置超出字符的长度,则返回。
如果.的数量==3,则表明已经到了最后面直接添加的时候,时候只要判断剩下的字符转成的数字是否大于255即可。
如果第一个字符是0,那么除非这个字符是最后一个字符,否则返回。
- 例如1.2.3.,后面还有04,那么加进来的只能是0,而4不能加进来
当在1位置的时候,就是start+3,即i的取值范围是(start,start+3)。
当在6的时候,就是start+3>len,会超出字符串长度,那么取值就只能是(start,len),这部分遍历是第三个.之前的,等加入第三个.之后是不会进来这里的。
如果当前层是0开头的,在加入一次0之后,后面的结果就不可能会再出现了
- 例如:10132,当第二个位置为0时:[1,0,1,32]、[1,0,13,2],这里0就不能再和第三个1组合变成01了,因此就得返回到第一层(也就是第一个1的回溯那一层).
var restoreIpAddresses = function(s) {
let res = [];
dfsHelper(s,[],0,res);
return res;
};
function dfsHelper(s,path,start,res) {
if(path.length === 4){
if(start === s.length){
res.push(path.join('.'))
}
return;
}
for(let i = 1;i<=3;i++){
let c = s.substr(start,i);
let num = parseInt(c,10);
if(c.length > 1 && c.charAt(0) === '0'){
break;
}
if(num >=0 && num<=255){
path.push(c);
dfsHelper(s,path,start+i,res);
path.pop();
}
}
}
思考
题目其实不是很难,回溯也简单,就是写起来是真难写,剪枝剪的乱七八糟。
感谢阅读,希望能对你有所帮助,文章若有错误或者侵权,可以在评论区留言或在我的主页添加公众号联系我。
写作不易,如果觉得不错,可以「点赞」+「评论」 谢谢支持❤