给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。
示例:
输入: "25525511135"
输出: ["255.255.11.135", "255.255.111.35"]
输入:"0000"
输出:["0.0.0.0"]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/restore-ip-addresses
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
暴力枚举
居然能击败100%的人?
思路:
网络结构是固定的4层,所以我们可以直接用暴力枚举的方式进行,边枚举、边判断,这样可以省去好多无效的结果判断,保证往下的每一次操作都是有效的。
class Solution {
public:
// 暴力枚举
vector<string> restoreIpAddresses(string s) {
vector<string> re;
if(s.size() < 4) return re;
for(int i = 0; i < 3 && i < s.size(); ++i) {
// 第一层
if(s.substr(0,1) == "0" && i >= 1) // 不能有 011.111之类的 ,可以有 0.111
continue;
int len1 = s.size() - i - 1;
// 排除无关情况
if(len1 > 9 || len1 < 3) // 剩余的长度必须符合要求,否则不用继续进行
continue;
if(i == 2 && atoi((s.substr(0, 3)).c_str()) > 255) // 当前层的长度为3的时候判断这个数值大于255没有
continue;
for(int j = i + 1; j <= i + 3 && j < s.size(); ++j) {
// 第二层
if(s.substr(i+1,1) == "0" && j - i > 1)
continue;
int len2 = s.size() - j - 1;
if(len2 > 6 || len2 < 2)
continue;
if(j - i == 3 && atoi((s.substr(i + 1, 3)).c_str()) > 255)
continue;
for(int k = j + 1; k <= j + 3 && k < s.size(); ++k) {
// 第三层
if(s.substr(j+1,1) == "0" && k - j > 1)
continue;
int len3 = s.size() - k - 1; // 第三层后剩余的长度
if(len3 > 3 || len3 <= 0)
continue;
if(k - j == 3 && atoi((s.substr(j + 1, 3)).c_str()) > 255)
continue;
if(s.substr(k+1, 1) == "0" && len3 > 1)
continue;
if(len3 == 3 && atoi(s.substr(k+1, 3).c_str()) > 255)
continue;
string re_str = s.substr(0, i + 1) + "." + s.substr(i+1, j - i) + "." + s.substr(j+1, k-j) + "." + s.substr(k+1, len3);
re.push_back(re_str);
}
}
}
return re;
}
};
DFS方式
class Solution {
public:
// dfs方式
vector<string> restoreIpAddresses(string s) {
vector<string> re;
if(s.size() < 4) return re;
string temp = "";
dfs(re, s, 1, 0, temp);
return re;
}
void dfs(vector<string> &re,const string& s, int depth, int start, string &temp) {
if(start >= s.size())
return;
for(int i = start; i < start + 3 && i < s.size(); ++i) {
// 计算剩余长度
int len = s.size() - i - 1;
// 剩余的长度不符合要求时候
if(len > (4-depth) * 3 || len < (4-depth))
continue;
// 该层次长度大于1,但是开头为0是不被允许的 eg:011
if(i - start > 0 && s.substr(start, 1) == "0")
continue;
// 该层次长度为3,但是大小超过255的时候是不被允许的
if(i - start == 2 && atoi(s.substr(start, 3).c_str()) > 255)
continue;
string cur_str = s.substr(start, i-start+1);
string cur_temp = temp + cur_str;
if(depth != 4)
cur_temp += ".";
if(depth == 4 && i == s.size() - 1) {
re.push_back(cur_temp);
return;
}
dfs(re, s, depth + 1, i + 1, cur_temp);
}
}
};