leetcode 复原 IP 地址 中等

leetcode 复原 IP 地址 中等

 

 

如果 s.size() > 12 或者 < 4, 直接 return, 这个无话可说..

然后就是枚举三个点的位置, 判断每个部分是否含前缀 0 和是否小于 255 即可。

如,第一部分只可能是 下标为 i ∈ [0, 2],然后第二部分则为 j ∈ [i + 1, i + 3],第四部分为 k ∈ [sz - 3, sz - 1],第三部分则是剩余的。

然后其实这样枚举可能出现越界的问题,比如给出字符串总长度为 4, i 的边界实际上到不了 2。但是不在 for 循环范围中处理边界,使用计算这个部分的大小来判断是否合法,即代码中的 sz1, sz2, sz3, sz4.

class Solution {
public:
    vector<string> restoreIpAddresses(const string &s) {
        if(s.size() > 12 || s.size() < 4) return {};
        vector<string> ret;
        int sz = s.size();
        for(int i = 0; i <= 2; ++ i) {  // [0, i] 第一部分
            for(int j = i + 1; j <= i + 3; ++ j) {  // [i + 1, j] 为第二部分
                for(int k = sz - 1; k >= sz - 3; -- k) {    // [k, sz - 1] 为第四部分, [j + 1, k - 1] 为第三部分
                    int sz1 = i + 1, sz2 = j - (i + 1) + 1;
                    int sz3 = (k - 1) - (j + 1) + 1, sz4 = sz - 1 - k + 1;
                    if(!check(s, 0, sz1) || !check(s, i + 1, sz2) ||
                       !check(s, j + 1, sz3) || !check(s, k, sz4)) continue;
                    string tmp;
                    insert(s, tmp, 0, sz1); tmp.push_back(.);
                    insert(s, tmp, i + 1, sz2); tmp.push_back(.);
                    insert(s, tmp, j + 1, sz3); tmp.push_back(.);
                    insert(s, tmp, k, sz4);
                    ret.emplace_back(std::move(tmp));
                }
            }
        }
        return ret;
    }

private:
    bool check(const string &s, int i, int sz) {
        if(sz <= 0) return false;
        if(sz > 1 && s[i] == 0) return false; // 前导 0
        int num = 0;
        for(int j = i; j < i + sz; ++ j) {
            num = num * 10 + (s[j] - 0);
        }
        return num <= 255;
    }

    void insert(const string &s, string &tmp, int i, int sz) {
        for(int j = i; j < i + sz; ++ j) {
            tmp.push_back(s[j]);
        }
    }
};

 

leetcode 复原 IP 地址 中等

上一篇:paraview计算面上的流量


下一篇:51nod 5~7 级 DP 题版刷记录