开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第31天,点击查看活动详情
引言
算法的技能对于程序员是百益而无一害,作为程序员无论是前端还是后端算法技能对于我们都是十分十分的重要,我将陆续整理并讲解前端程序员必须掌握的经典算法。
题目描述
有效 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"]
示例 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"]
提示:
1 <= s.length <= 20s仅由数字组成
分析
根据题目的分析,我们如何求复原IP地址的过程?根据题目的要求我们可以基于回溯的设计完成。
- 设计回溯递归函数
- 根据ip地址的特点判断符合条件
- 四位数字不断地回溯交换位置
- 返回结果。
分析整个设计的过程,整体的时间复杂度是o(n^2),因此设计还是比较简单的。
解答
```
/**
* @param {string} s
* @return {string[]}
*/
var restoreIpAddresses = function(s) {
//1.复原ip递增
//四个段位的构成啊,我笑了,
const main = str => {
if(str.length===0) return false;
if(Number(str)<0 || Number(str)>255) return false;
if(str.length>=2 && str[0]==='0') return false;
return true;
}
let res = [];
for(let a=1;a<4;a++) {
for(let b=1;b<4;b++) {
for(let c=1;c<4;c++) {
let str0 = s.slice(0,a);
let str1 = s.slice(a,a+b);
let str2 = s.slice(a+b,a+b+c);
let str3 = s.slice(a+b+c);
if(main(str0) && main(str1) && main(str2) && main(str3)) {
//判断是否存在重复元素的出现
let tmp = str0+"."+str1+"."+str2+"."+str3;
if(!res.includes(tmp)) {
res.push(tmp);
}
}
}
}
}
return res;
};
```
复原ip地址的核心设计就是依赖于回溯的过程完成,整体的设计还是比较容易出错。