LeetCode-----第九十三题-----复原IP地址

复原IP地址

难度:中等

给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。

有效的 IP 地址正好由四个整数(每个整数位于 0 到 255 之间组成),整数之间用 '.' 分隔。

 

示例:

输入: "25525511135"
输出: ["255.255.11.135", "255.255.111.35"]

题目分析:

  回溯法,得将字符串分成四个部分,每个部分要满足条件。

  结束条件:n == 4,然后进行res存储

  all station:使用for循环,i = 1,传入参数为n+1(仅作为计数器),剪枝(val>255 或者 i!=to_string(val).size()开头为0)

 

参考代码:

class Solution {
public:
	vector<string> restoreIpAddresses(string s) {
		string ip;
        vector<string> res;
        back_search(res,0,s,ip);
		return res;
	}

    void back_search(vector<string>& res, int n, string s, string ip)
    {
        if(n == 4)
        {
            if(s.empty())
                res.push_back(ip);
        }else{
            for(int i = 1; i < 4; i++)
            {
                if(s.size() < i) //字符串分完了,后面没得分了,就返回
                    break;
                int temp = stoi(s.substr(0,i));//将字符串转换为数字
                if(temp > 255 || i != std::to_string(temp).size())//temp大于255或者开头为0均为无效IP
                    break;
                back_search(res,n+1,s.substr(i),ip + s.substr(0,i)+(n==3 ? "" : "."));
            }
        }
    }
};

 

参考代码:(上面代码有点骚气,看看这个版本)

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

		string temp;
		back_search(s, res, temp, 0);
		return res;
	}

	void back_search(string s, vector<string>& res, string temp, int count)
	{
		//结束条件
		if (count == 4)
		{
			if (!s.empty())//如果还有剩余的字符串,说明没分完,就不压入res中
				return;
			temp.pop_back();//去掉最后一个‘.’,因为是值引用,所以不影响回溯
			res.push_back(temp);
			return;
		}

		//all station
		for (int i = 1; i < 4; i++)
		{
			if (i <= s.size())//不让i越界,如果一共只有4个字符,每个位置分三个字符也不现实
			{
				string str = s.substr(0, i);//将0~i的子串提取出来
				int data = stoi(str);//换算成数字,方便下面条件判断
                //如果有两个及以上的字符,开头是不能为0的,也不能超过255(IP划分规则)
                //不满足规则的,直接返回
				if (str[0] == '0' && str.size() > 1 || data > 255)
					return;
                //把字符串和‘.’存储起来
				temp += str;
				temp.push_back('.');
				back_search(s.substr(i), res, temp, count + 1);//递归并计数
				for (int j = 0; j < str.size() + 1; j++)//字符串不能一次性pop
					temp.pop_back();
			}
		}
	}
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值