1. 程式人生 > 其它 >|NO.Z.00009|——————————|ManageMent|——|Linux&服務管理.V05|

|NO.Z.00009|——————————|ManageMent|——|Linux&服務管理.V05|

✅做題思路or感想

這種字串切割的問題都可以用回溯法來解決

遞迴三部曲:

  • 遞迴引數

    • 因為要切割字串,所以要用一個startIndex來控制子串的開頭位置,即是會切割出一個範圍是[startIndex, i]的子串
  • 遞迴中止條件

    • 這裡因為IP地址有正好四個整數(子串)構成,所以當切割的子串數量為4時就可以了。然後因為這四個子串組合起來要正好是主串,所以還需要startIndex超過主串的最後一位,即s.size() - 1才行
  • 遞迴單層邏輯

    • 判斷子串是否符合條件,符合後便把子串放入vector<string>
  • 判斷條件

    1. 不能有前導0
    2. 子串長度不超過3
    3. 不能有除了數字外的其他字元
    4. 子串轉化成的數字範圍要在[0, 255]
class Solution {
public:
    vector<string>result;
    vector<string>temp;
    bool isGood(string s, int startIndex, int i) {
        //子串長度限制
        if (i - startIndex + 1 >= 4)return false;
        string str = s.substr(startIndex, i - startIndex + 1);
        //由子串轉化成的數字的範圍的限制
        if (0 > stoi(str) || stoi(str) > 255)return false;
        //前導0的限制
        if (str.size() > 1 && str[0] == '0')return false;
        //非法字元的限制
        for (int j = 0; j < str.size(); j++) {
            if (str[j] >= '0' && str[j] <= '9')continue;
            else return false;
        }
        return true;
    }
    void dfs(string s, int startIndex) {
        //遞迴中止條件
        if (temp.size() == 4 && startIndex >= s.size()) {
            string str;
            //需要把子串拿出來做一點加工後再放到result中!!!
            for (int i = 0; i < temp.size(); i++) {
                if (i != temp.size() - 1) {
                    str = str + temp[i] + ".";
                } else {
                    str = str + temp[i];
                }
            }
            result.push_back(str);
            return;
        }
        for (int i = startIndex; i < s.size(); i++) {
            if (isGood(s, startIndex, i)) {
                string str = s.substr(startIndex, i - startIndex + 1);
                temp.push_back(str);
                dfs(s, i + 1);
                temp.pop_back();	//回溯
            } 
        }
    }
    vector<string> restoreIpAddresses(string s) {
        dfs(s, 0);
        return result;
    }
};