方法一:递归+回溯

题设可知,IP地址是由四段数字组成的数字序列,中间使用“.”连接起来,每段数字处于[0, 255]之间。所以我们可以将问题分解为:得到上一段数字后,从余下的字符串求剩余几段的数字。

1、从字符串的起点开始,得到第一段数字,由题设可知,每一段的数字都不会超过三位数,所以遍历前三个数字;

2、下一段数字从上一段数字的后一位开始向后遍历,递归得到所有的可能性。通过对每段数字进行有效性判断,四段数字都满足有效性的是有效的IP地址,存入数组中。

时间复杂度:o(3n)

空间复杂度:o(n)

class Solution {
  private:
    // 存储所有可能的IP地址
    vector<string> res;
    // 可能的IP地址
    string nums;
  public:
    vector<string> restoreIpAddresses(string s) {
        // 特殊情况处理
        if (s.length() < 4)
            return res;

        dfs(s, 0, 0);
        return res;
    }

    void dfs(string s, int step, int idx) {
        // 存储当前段的字符
        string cur = "";

        if (step == 4) {
            if (idx == s.length())
                res.push_back(nums);
            else
                return;
        } else {
            for (int i = idx; i < idx + 3 && idx < s.length(); i++) {
                // 记录便于后续回溯
                string temp = nums;
                cur += s[i];
                int num = stoi(cur);
                // 数字在有效范围内且前置不能有多个0
                if (num <= 255 && (cur.length() == 1 || cur[0] != '0')) {
                    if (step != 3)
                        nums += cur + ".";
                    else
                        nums += cur;
                    // 递归得到下一段的IP
                    dfs(s, step + 1, i + 1);
                    // 回溯
                    nums = temp;
                }
            }
        }
    }
};

方法二:暴力迭代

暴力迭代,遍历所有的可能性将字符串分为四段数字,每段数字都符合IP地址的有效性的压入数组。

class Solution {
  private:
    vector<string> res;
  public:
    vector<string> restoreIpAddresses(string s) {
        // 特殊情况处理
        if (s.length() < 4)
            return res;

        string nums1, nums2, nums3, nums4;
		// 循环三次,遍历所有可能
        for (int i = 0; i < 3 && i < s.length() - 3; i++) {
            for (int j = i + 1; j < i + 4 && j < s.length() - 2; j++) {
                for (int k = j + 1; k < j + 4 && k < s.length() - 1; k++) {
                    nums1 = s.substr(0, i + 1);
                    nums2 = s.substr(i + 1, j - i);
                    nums3 = s.substr(j + 1, k - j);
                    nums4 = s.substr(k + 1, s.length() - k - 1);

                    if ((stoi(nums1) <= 255 && (nums1.length() == 1 || nums1[0] != '0')) &&
                            (stoi(nums2) <= 255 && (nums2.length() == 1 || nums2[0] != '0')) &&
                            (stoi(nums3) <= 255 && (nums3.length() == 1 || nums3[0] != '0')) &&
                            (stoi(nums4) <= 255 && (nums4.length() == 1 || nums4[0] != '0'))) {
                        res.push_back(nums1 + "." + nums2 + "." + nums3 + "." + nums4);
                    }
                }
            }
        }

        return res;
    }
};