题目

image.png

思路

  • 一定有提前剪枝的办法,但是这题数据量不大,所以不明显,希望下次有空想一想
  • 回溯的树当中,往下多走一层,就多加一个.,每次去1位或2位或3位,意味着1个节点有3个孩子。
  • 终止递归是2个条件,第1,起始位置超过总长度,第2,到达了最后一层。

    代码

  1. class Solution {
  2. public:
  3. bool checkFit(vector<string> cur_address, string origin_s) {
  4. int all_len = 0;
  5. for (string address: cur_address) {
  6. // 防止 023 这样的情况出现,读掉前置的0
  7. if (address[0] == '0' && address.size() > 1) {
  8. return false;
  9. }
  10. all_len += address.size();
  11. int cur_num = std::stoi(address);
  12. if (cur_num < 0 || cur_num > 255) {
  13. return false;
  14. }
  15. }
  16. return all_len == origin_s.size();
  17. }
  18. void backTrack(vector<vector<string>>& all_addresses, vector<string>& cur_address, string origin_s, int cur_depth, int& begin_pos) {
  19. // 还可以改剪枝条件,加快速度,但是我比较懒,所以不写了
  20. if (begin_pos > origin_s.size()) {
  21. return;
  22. }
  23. if (cur_depth == 4) {
  24. if (checkFit(cur_address, origin_s)) {
  25. all_addresses.push_back(cur_address);
  26. }
  27. return;
  28. }
  29. for (int frag_len = 1; frag_len <= 3; ++frag_len) {
  30. cur_address.push_back(origin_s.substr(begin_pos, frag_len));
  31. begin_pos += frag_len;
  32. backTrack(all_addresses, cur_address, origin_s, cur_depth + 1, begin_pos);
  33. begin_pos -= frag_len;
  34. cur_address.pop_back();
  35. }
  36. }
  37. vector<string> restoreIpAddresses(string s) {
  38. vector<vector<string>> all_addresses;
  39. vector<string> cur_address;
  40. int begin_pos = 0;
  41. backTrack(all_addresses, cur_address, s, 0, begin_pos);
  42. vector<string> fit_addresses;
  43. for (vector<string> address: all_addresses) {
  44. string fit_address;
  45. for (string fragment_address: address) {
  46. fit_address += fragment_address;
  47. fit_address += '.';
  48. }
  49. // 去掉最后的一个 '.'
  50. fit_addresses.push_back(fit_address.substr(0, fit_address.size() - 1));
  51. }
  52. return fit_addresses;
  53. }
  54. };