力扣93-复原IP地址

这道题本质是在分隔字符串,需要把给定的字符串分割成四个部分,每个部分满足IP地址的条件就是正确的IP地址,分割的题用回溯解决。

这道题难点在于判断情况比普通回溯题的情况要复杂一些,比如有很多种情况让程序回溯回去,而不只是一俩个确定的不满足条件。

判断IP地址是否正确:

首先根据题目描述,一个正确的IP地址由四个IP分段组成,每个IP分段有数字大小和格式的限制,观察发现每个IP分段最多由三位数构成,最少由一位数构成,四个IP分段必须都是这个标准,由此可以得出判断IP地址是否正确的条件。

如果满足正确IP地址条件,就推入准备好的 res 结果数组。

IP分段不正确的情况:

1.如果某部分达到了三位数,且该部分数值大于255

2.某部分长度不为 1 ,但是该部分开头元素为 0 

3.最后一部分IP分段达到每一种情况时,给定的字符串还没有用尽。

递归函数

我们需要一个参数 start 来表示每次从字符串的哪个位置开始进行分隔,但是每个 start 开始构建该部分IP分段都会有三种情况:

1.一位数;2.俩位数;3.三位数;

所以每次从 start 开始构建该部分IP分段的时候都要遍历三次,每一次取对应位数的IP分段,对每次取出来的IP分段都要进行判断该IP分段是否符合要求,如果符合要求就推入待定数组 path 。

处理IP分段不正确情况3的思路:

该情况下IP分段为最后一段,想要使整体符合正确IP地址的要求,最后一段IP分段肯定是要用尽给定的字符串的,怎么判断是否用尽了呢?

由于每一个IP分段都是从给定字符串的本次起始位置 与 达到该IP分段三种不同长度的某一种位置截取的,

即判断:该种最后一段IP分段位数情况之一的 起始位置 + 当前是最后IP分段哪一种长度  是否等于  给定字符串的长度,如果是的话,就证明最后一段IP分段的该种位数情况正好用尽了给定字符长度,则是正确的最后IP分段。

回溯:

每次遇到不符合要求的IP分段情况,就退回到上一个状态继续寻找。

代码如下:

var restoreIpAddresses = function (s) {

    const res = [];
    const backtrack = (path, start) => {
        // 符合有效IP地址的总判断
        if (path.length === 4 && start === s.length) {
            res.push(path.join('.'));
            return;
        }
        // 不符合最终有效IP则返回
        if (path.length === 4 && start < s.length) {
            return;
        }
        // 从每一个IP分段的起始位置开始,有三种该段情况(子段长度分别为1,2,3)
        for (let len = 1; len <= 3; len++) {
            // 加上本次IP分段位数的长度越界
            if (start + len -1 > s.length) return;
            // 该IP分段位数不为 1 但是开头为 0
            if (len > 1 && s[start] == '0') return;
            // IP分段位数为3时,是否超出255
            let str = s.slice(start, start + len);
            if (len === 3 && +str > 255) return;
            // 符合IP分段情况,推入待定数组
            path.push(str);
            // 注意这个 start + len 用来判断最后部分的IP分段是否用尽了给定字符串
            backtrack(path, start + len);
            // 回溯:返回上一个状态
            path.pop();
        }
    }
    backtrack([], 0);
    return res;
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值