93 复原IP地址

复原IP地址

给定一个只包含数字的字符串,复原它并返回所有可能的 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 地址。

示例1

输入:s = “25525511135”
输出:[“255.255.11.135”,“255.255.111.35”]

示例2

输入:s = “0000”
输出:[“0.0.0.0”]

示例三

输入:s = “1111”
输出:[“1.1.1.1”]

示例4

输入:s = “010010”
输出:[“0.10.0.10”,“0.100.1.0”]

示例5

输入:s = “101023”
输出:[“1.0.10.23”,“1.0.102.3”,“10.1.0.23”,“10.10.2.3”,“101.0.2.3”]

思路一:暴力解法

找出所有可能的情况,并逐一判断每位整数 是否是 有效的IP地址

class Solution {
public:
    vector<string> restoreIpAddresses(string s) {
        vector<string> result;
        
        if (s.size() < 4 || s.size() > 12) {
            return result;
        }

        for (int i = 1; i < s.size() - 2; i++)
        {
            string temp1 = s.substr(0, i);
            if (temp1.size() > 1 && temp1[0] == '0') {
                continue;
            }

            for (int j = i + 1; j < s.size() - 1; j++)
            {
                string temp2 = s.substr(i, j - i);
                if (temp2.size() > 1 && temp2[0] == '0') {
                    continue;
                }

                for(int k=j+1;k<s.size();k++)
                {
                    string temp3=s.substr(j,k-j);
                    if (temp3.size() > 1 && temp3[0] == '0') {
                        continue;
                    }

                    string temp4 = s.substr(k, s.size() - k);
                    if (temp4.size() > 1 && temp4[0] == '0') {
                        continue;
                    }

                    bool invalidIp = (stoi(temp1) > 255) || (stoi(temp2) > 255) || (stoi(temp3) > 255) || (stoi(temp4) > 255);

                    if (invalidIp) {
                        continue;
                    }

                    result.push_back(temp1 + "." + temp2 + "." + temp3 + "." + temp4);
                }
            }
        }

        return result;
    }
};

思路二:回溯解法

思路

我们知道最终合法的IP地址会被分为四个整数段,而每个整数段的数字位数范围为1~3,那么我们就依据每个整数段的位数作为回溯列表,进行回溯

在这里插入图片描述

其中图中的圈1,圈2图,均是由于剩余第四段不满足每个整数段小于255被淘汰掉了
依据这种方法,只有圈3中的最后两种符合要求

代码

class Solution {
public:
    vector<string> restoreIpAddresses(string s)
    {
        vector<string> result;

        if (s.size() < 4 || s.size() > 12)
        {
            return result;
        }

        dfs(s, 1, "", result);
        return result;
    }

    //n为整数段数,合法IP地址为4段
    void dfs(string s, int n, string ipaddr, vector<string> &result)
    {
        if (n == 5 && s.size() == 0) {
            result.push_back(ipaddr.substr(0, ipaddr.size() - 1));
        }

        if (n > 5) {
            return;
        }

        for (int i = 1; i <= 3; i++)  //i为每段的整数回溯时的可选择位数
        {
            if (s.size() < i) {
                return;
            }
            string temp = s.substr(0, i);
            if (temp.size() != 1 && temp[0] == '0') {
                return;
            }

            if (stoi(temp) > 255) {
                return;
            }

            dfs(s.substr(i), n + 1, ipaddr + temp + '.', result);
        }
    }
};

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值