力扣算法ing(60 / 100)
4.19 回溯合集—93复原ip地址
有效 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"]
我的思路:
四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 ‘.’ 分隔
数字的字符串 s ,用以表示一个 IP 地址,返回所有可能的有效 IP 地址
相邻
101023
类似于切割回文串,但是在回溯当中应该如何处理判断它是否是有效的IP地址呢?
如何判断是有效的IP地址:
每个整数位于 0
到 255
之间组成,且不能含有前导 0
前导0:长度大于1而且第一个字符为0
为空数组[]
只能为三个点
啊啊啊啊又是空数组
不应该是将isIp传入的字符串进行循环转为数字和0以及255比较,应该是整个子串来比较
乱七八槽的数据啊啊啊啊啊啊
aaaa终于过了,好艰辛!
高频错误!!!只能为三个点
这个条件我一直没有注意,我的天!有很多点,我真的想笑
if(startIndex === s.length && point === 4){// ip地址.分割res.push(path.join('.'));}if(point === 4){return false;}
不应该是将isIp传入的字符串进行循环转为数字和0以及255比较,应该是整个子串来比较
substring:注意,这个是割前不包后
最终代码:
function restoreIpAddresses(s: string): string[] {const path = [];const res = [];let point = 0;function backingTraking(startIndex : number){if(startIndex === s.length && point === 4){// ip地址.分割res.push(path.join('.'));}if(point === 4){return false;}for(let i = startIndex ; i < s.length ; i++){// 处理节点// 注意!substring:取前不取后const newStr = s.substring(startIndex , i + 1);if(!isIp(newStr)){continue;}path.push(newStr);point++;backingTraking(i + 1);path.pop();point--;// 每个段最多为三位if(i - startIndex + 1 === 3){break;}}}//判断是否为正确的IP// 这里应该是子串// 如何判断IP地址:每个整数位于 0 到 255 之间// 且不能含有前导 0function isIp(s :string){if(s.length > 1 && s[0] === '0'){// 不能含有前导 0return false;}//比较的是整个子串const num = parseInt(s , 10);return num <= 255 && num >= 0; // 确保数字在0到255之间}backingTraking(0);return res;};
总结:其实这道题还是很有难度的(苦笑),但是在上一个题目的基础上我居然觉得还行哈哈,因为他们在大体上都是相同的,都是在push之前判断条件,判断函数中传入的是一个子串,对子串进行判断是否为ip地址。有个很重要的点就是point数量的判断,因为只有3个,每个段最多为三位,要注意这个判断条件。