Given a string containing only digits, restore it by returning all possible valid IP address combinations.
Example:
Input: "25525511135"
Output: ["255.255.11.135", "255.255.111.35"]
方法1:
思路:
尝试放置三个点,每一次检查前面切出来的是否是0 - 255之间的数字,然后backtracking。
易错点
- 很长的corner case:用s.size()>12剪掉
- 要确保stoi的参数不是“”:i <= min(3, (int) s.size())
- 推入的条件
class Solution {
public:
vector<string> restoreIpAddresses(string s) {
vector<string> result;
restoreHelper(s, result, "", 3);
return result;
}
void restoreHelper(string s, vector<string> & result, string current, int dots) {
if (s.size() > 12) return;
if (dots == -1 && s.empty()) {
result.push_back(current);
return;
}
for (int i = 1;i <= min(3, (int)s.size()); i ++) {
string segment = s.substr(0, i);
string rest = s.substr(i);
if (rest.size() < dots) break;
if (segment.size() > 1 && segment[0] == '0') continue;
if (stoi(segment) <= 255 && stoi(segment) >= 0) {
if (dots > 0 ) {
restoreHelper(rest, result, current + segment + '.', dots - 1);
}
else {
restoreHelper(rest, result, current + segment, dots - 1);
}
}
}
return;
}
};
加速版:
grandyang: http://www.cnblogs.com/grandyang/p/4305572.html
tricks:
- k != std::to_string(val).size():比如当k=3时,说明应该是个三位数,但如果字符是"010",那么转为整型val=10,再转回字符串就是"10",此时的长度和k值不同了,这样就可以找出不合要求的情况了
- if (s.size() < k) break:“000”,此时如果k=3,不可能合法
class Solution {
public:
vector<string> restoreIpAddresses(string s) {
vector<string> res;
helper(s, 0, "", res);
return res;
}
void helper(string s, int n, string out, vector<string>& res) {
if (n == 4) {
if (s.empty()) res.push_back(out);
} else {
for (int k = 1; k < 4; ++k) {
if (s.size() < k) break;
int val = atoi(s.substr(0, k).c_str());
if (val > 255 || k != std::to_string(val).size()) continue;
helper(s.substr(k), n + 1, out + s.substr(0, k) + (n == 3 ? "" : "."), res);
}
}
}
};