93. Restore IP Addresses(复原IP地址)
1. 题目描述
给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。
有效的 IP 地址正好由四个整数(每个整数位于 0 到 255 之间组成),整数之间用 ‘.’ 分隔。
示例:
输入: “25525511135”
输出: [“255.255.11.135”, “255.255.111.35”]
2. 广度优先搜索(Breadth-First Search)
2.1 解题思路
和91. Decode Ways(解码方法)类似,我们可以把这道题看成路径问题,行走的规则如下:
- 可以向前走1、2、3步;
- 最多走4次,count <= 4;
- 走到序号末尾(idx == s.size()),算一个合法IP;
- 子串所代表的数字不能大于255;
- 1位数以上,开头不能为0;
根据上面的规则,递归方法就比较好理解啦:
2.2 实例代码
class Solution {
vector<string> ans;
vector<string> temp;
// 将string转换为int
bool convertToInt(string str) {
// if (str.size() > 1 && str[0] == '0') return false; // 一位数以上,开头不能为0
stringstream ss;
int num;
ss << str;
ss >> num;
return 0 <= num && num <= 255;
}
void bfs(string& s, int idx, int count) {
if (idx > s.size() || count > 4) return;
if (count == 4 && idx == s.size()) {
string s;
for (string& str : temp) s += str + ".";
s.pop_back(); // 去除最后一个"."
ans.push_back(s);
return;
}
if (convertToInt(s.substr(idx, 1))) { temp.push_back(s.substr(idx, 1)); bfs(s, idx + 1, count + 1); temp.pop_back(); } // 走一步
if (s[idx] == '0') return; // 一位数以上,开头不能为0
if (convertToInt(s.substr(idx, 2))) { temp.push_back(s.substr(idx, 2)); bfs(s, idx + 2, count + 1); temp.pop_back(); } // 走两步
if (convertToInt(s.substr(idx, 3))) { temp.push_back(s.substr(idx, 3)); bfs(s, idx + 3, count + 1); temp.pop_back(); } // 走三步
}
public:
vector<string> restoreIpAddresses(string s) {
if (s.empty()) return ans;
bfs(s, 0, 0);
return ans;
}
};
3. 深度优先搜索(Depth-First Search)
3.1 解题思路
这里的思路和上面差不太多,比较大的区别是不用最后拼接".“,我们递归一次拼接一个”.";然后用一个for循环表示走1、2、3步;
3.2 实例代码
class Solution {
vector<string> ans;
void dfs(string& s, int idx, int count, string str) {
if (idx == s.size() && count == 4) {
str.pop_back(); // 去除最后一个"."
ans.push_back(str);
return;
}
int len = s.size(); // 相减,unsigned integer避免溢出
if (len - idx > (4 - count) * 3 || len - idx < 4 - count) return; // 合法IP最多4 * 3位,最少4 * 1位
int num = 0;
for (int i = idx; i < idx + 3; i++) {
num = num * 10 + (s[i] - '0');
if (num < 256) { str.push_back(s[i]); dfs(s, i + 1, count + 1, str + "."); }
if (!num) break; // 一位数以上,开头不能为0
}
}
public:
vector<string> restoreIpAddresses(string s) {
dfs(s, 0, 0, "");
return ans;
}
};
4. 参考资料
镇楼图低俗禁止