题目地址:
https://leetcode.com/problems/restore-ip-addresses/
将一个只含数字的字符串转化为合法的IP地址。合法的IP地址的格式是,由小数点"."分隔开的四个大于等于 0 0 0小于等于 255 255 255的整数,如果是正数则不能以 0 0 0开头。比如 255.255.11.135 255.255.11.135 255.255.11.135, 0.0.0.0 0.0.0.0 0.0.0.0等等。
思路是用DFS暴搜。每次从某个位置出发,开始枚举当前新加入的那个大于等于 0 0 0小于等于 255 255 255的整数,其实也就是枚举从这个位置出发要分割原字符串多少个字符。只要满足条件,就进入下一层枚举,直到出发的位置已经到了字符串末尾(也就是到了递归树的叶子节点),就开始判断,如果已经切割出了四个数字,就说明当前的切割合法,加入res;否则直接return。代码如下:
class Solution {
public:
vector<string> restoreIpAddresses(string s) {
vector<string> res;
string p;
dfs(0, p, 0, s, res);
return res;
}
void dfs(int u, string& p, int cut, string& s, vector<string>& res) {
if (u == s.size()) {
if (cut == 4) res.push_back(p.substr(0, p.size() - 1));
return;
}
for (int i = u; i < s.size(); i++) {
string cur = s.substr(u, i - u + 1);
if ((cur[0] != '0' || cur == "0") && stoi(cur) <= 255 && cut < 4) {
p += cur + ".";
dfs(i + 1, p, cut + 1, s, res);
p.erase(p.size() - cur.size() - 1);
} else if (cur.size() > 3)
break;
}
}
};
时间复杂度 O ( 3 4 ) O(3^4) O(34)(实际上时间复杂度是常数量级的,因为递归树最多 4 4 4层,每层三个叉,所以整棵树的节点个数有个常数的上界),空间 O ( 16 ) O(16) O(16)。