🌈【LeetCode 93. 复原 IP 地址 】- JavaScript(回溯+剪枝)

136 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第10天,点击查看活动详情


说明:文章部分内容及图片出自网络,如有侵权请与我本人联系(主页有公众号:小攻城狮学前端)

作者:小只前端攻城狮、 主页:小只前端攻城狮的主页、 来源:掘金

GitHub:P-J27、 CSDN:PJ想做前端攻城狮

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


【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();
        }
    }
}

思考

题目其实不是很难,回溯也简单,就是写起来是真难写,剪枝剪的乱七八糟。


感谢阅读,希望能对你有所帮助,文章若有错误或者侵权,可以在评论区留言或在我的主页添加公众号联系我。

写作不易,如果觉得不错,可以「点赞」+「评论」 谢谢支持❤