题目描述
现在有一个只包含数字的字符串,将该字符串转化成IP地址的形式,返回所有可能的情况。
例如:
给出的字符串为"25525522135",
返回["255.255.22.135", "255.255.221.35"].
方法一:暴力求解
求解思路
直接对所给的字符串进行枚举,因为IP地址每一个位置可能有1到3个数字,因此我们对每一个位置进行1到3字符串大小的遍历。这样既可求出所有的IP地址
解题代码
class Solution { public: bool justify(string s)//参考漫漫云天自翱翔的code { if(s.size() != 1 && s[0] == '0' || stoi(s) > 255) return true; //这个地方判断IP地址的时候,是为了防止出现大于255的数字组合出现, //并且防止类似025这种类型的数字组合出现! return false; } vector<string> restoreIpAddresses(string s) { // write code here vector<string> ans; for(int i = 1;i<=3;i++) { //第一位的长度 for(int j = 1;j<=3;j++) { //第二位的长度 for(int m = 1;m<=3;m++) { //第三位的长度 for(int n = 1;n<=3;n++) { // 第四位的长度 if((i+j+m+n)==s.size()) { string s1 = s.substr(0,i);//取子串 string s2 = s.substr(i,j); string s3 = s.substr(i+j,m); string s4 = s.substr(i+j+m,n); if(!justify(s1)&&!justify(s2)&&!justify(s3)&&!justify(s4)) { string tt = s1 + "." +s2 +"." +s3 +"." +s4; //拼接 ans.push_back(tt);//将所有结果进行保存,最后输出结果。 } } } } } } return ans; } };
复杂度分析
时间复杂度:因为四个遍历都是从1到3的循环,为常数,因此为O(1)
空间复杂度:使用子串,空间复杂度为O(1)
方法二:递归的思想
求解思路
使用递归的思想,把数字字符串进行分割,然后在分割的基础上面继续分割,如果遇到不符合IP地址的格式,则这一“分支”的递归就结束,然后再看其他分割的结果。
其中参考杭电 De梦的终止条件和段位合法性,我们有:当IP地址的点的数量达到3个时,停止递归。对于段位的合法性,可以参考方法一的暴力法求解,即不能出现格式不符合IP地址的数字组合。
解题代码
class Solution { private: vector<string> result;// 记录结果 参考杭电 De梦的code void backtracking(string& s, int startIndex, int pointNum)//startIndex:搜索的起始位置,pointNum:添加逗点的数量 { if (pointNum == 3) { // 逗点数量为3时,分隔结束 // 判断第四段子字符串是否合法,如果合法就放进result中 if (isValid(s, startIndex, s.size() - 1)) { result.push_back(s); } } for (int i = startIndex; i < s.size(); i++) { if (isValid(s, startIndex, i)) { // 判断 [startIndex,i] 这个区间的子串是否合法 s.insert(s.begin() + i + 1 , '.'); // 在i的后面插入一个逗点 pointNum++; backtracking(s, i + 2, pointNum); // 插入逗点之后下一个子串的起始位置为i+2 pointNum--; // 回溯 s.erase(s.begin() + i + 1); // 回溯删掉逗点 } else break; // 不合法,直接结束本层循环 } } bool isValid(const string& s, int start, int end) { if (start > end) { return false;// 判断字符串s在左闭又闭区间[start, end]所组成的数字是否合法 } if (s[start] == '0' && start != end) { return false;//0开头不合法 } int num = 0; for (int i = start; i <= end; i++) { if (s[i] > '9' || s[i] < '0') //非正整数字符不合法 { return false; } num = num * 10 + (s[i] - '0'); if (num > 255) // 段位值大于255不合法 { return false; } } return true; } public: vector<string> restoreIpAddresses(string s) { result.clear(); if (s.size() > 12) return result; backtracking(s, 0, 0); return result; } };
复杂度分析
时间复杂度:递归所消耗的时间,为O( )(参考De 梦)
空间复杂度:递归使用的空间,O(N)