题目
思路
- 一定有提前剪枝的办法,但是这题数据量不大,所以不明显,希望下次有空想一想
- 回溯的树当中,往下多走一层,就多加一个
.
,每次去1位或2位或3位,意味着1个节点有3个孩子。 - 终止递归是2个条件,第1,起始位置超过总长度,第2,到达了最后一层。
代码
class Solution {
public:
bool checkFit(vector<string> cur_address, string origin_s) {
int all_len = 0;
for (string address: cur_address) {
// 防止 023 这样的情况出现,读掉前置的0
if (address[0] == '0' && address.size() > 1) {
return false;
}
all_len += address.size();
int cur_num = std::stoi(address);
if (cur_num < 0 || cur_num > 255) {
return false;
}
}
return all_len == origin_s.size();
}
void backTrack(vector<vector<string>>& all_addresses, vector<string>& cur_address, string origin_s, int cur_depth, int& begin_pos) {
// 还可以改剪枝条件,加快速度,但是我比较懒,所以不写了
if (begin_pos > origin_s.size()) {
return;
}
if (cur_depth == 4) {
if (checkFit(cur_address, origin_s)) {
all_addresses.push_back(cur_address);
}
return;
}
for (int frag_len = 1; frag_len <= 3; ++frag_len) {
cur_address.push_back(origin_s.substr(begin_pos, frag_len));
begin_pos += frag_len;
backTrack(all_addresses, cur_address, origin_s, cur_depth + 1, begin_pos);
begin_pos -= frag_len;
cur_address.pop_back();
}
}
vector<string> restoreIpAddresses(string s) {
vector<vector<string>> all_addresses;
vector<string> cur_address;
int begin_pos = 0;
backTrack(all_addresses, cur_address, s, 0, begin_pos);
vector<string> fit_addresses;
for (vector<string> address: all_addresses) {
string fit_address;
for (string fragment_address: address) {
fit_address += fragment_address;
fit_address += '.';
}
// 去掉最后的一个 '.'
fit_addresses.push_back(fit_address.substr(0, fit_address.size() - 1));
}
return fit_addresses;
}
};