Leetcode|分割|93.复原 IP 地址(first索引+多条件剪枝)

在这里插入图片描述

在这里插入图片描述

1 回溯法(first索引+剪枝)

在这里插入图片描述
本题讲真,略有麻烦,倒不是需要复杂的方法,而是根据题目要求需要多个判断才能保证AC,需要判断的条件如下

  • 只能分成4段
  • 每段数字个数∈[1, 3]
  • 每段数字个数多于1个时首个数字不能是0
  • 每段数字个数为3时不能大于255
  • 标点符号处理
class Solution {
public:
    string path;
    vector<string> res;

    bool vaild(string& s) {
        int size = s.size();
        if (size > 3) return false;
        if (s[0] == '0' && size > 1) return false;
        int a = 0;
        for (int i = 0; i < size; i++) 
            a += (s[i] - '0') * pow(10, size - 1 - i);
        if (a > 255) return false;
        return true;
    }

    void backtrack(string& s, int first, int len) {
        if (s.size() == path.size() - 3 && len == 4) {
            res.emplace_back(path);
            return;
        }
        if (len > 4) return;
        for (int i = first; i < first + 3 && i < s.size(); i++) {
            string substr = s.substr(first, i - first + 1);
            if (!vaild(substr)) continue;
            if (len <= 2) substr += '.';
            path += substr;
            backtrack(s, i + 1, len + 1);
            path = path.substr(0, path.size() - substr.size());
        }
    } 

    vector<string> restoreIpAddresses(string s) {
        backtrack(s, 0, 0);
        return res;
    }
};
class Solution {
private:
    int size;
    vector<string> solution;
    string path;
    const int UNIT_LEN = 3;  // 每段最长UNIT_LEN
    const int SEG_LEN = 4;   // 分成SEG_LEN个段
public:
    bool notValid(string& str) {
        // 3.每段数字个数多于1个时首个数字不能是0
        if (str.size() > 1 && str[0] == '0') return true;
        // 4.每段数字个数为3时不能大于255
        if (str.size() == UNIT_LEN && str > "255") return true;
        return false;
    }
    void backtrack(string& str, int first, int len) {
        if (first == size && len == SEG_LEN) {
            solution.emplace_back(path);
            return;
        } 
        // 1.只能分成4段
        if (len > SEG_LEN) return;
        // 2.每段数字个数∈[1, 3](段外右分支收紧)
        if (UNIT_LEN * (SEG_LEN - len) < size - first) return;
        // 2.每段数字个数∈[1, 3](段内右分支收紧)
        for (int i = first; i < size && i < first + UNIT_LEN; i++) {
            string subStr = str.substr(first, i - first + 1);
            if (notValid(subStr)) continue;
            subStr = path.empty() ? subStr : '.' + subStr;   // 标点符号处理
            path += subStr;
            backtrack(str, i + 1, len + 1);
            path = path.substr(0, path.size() - subStr.size());
        }
    }
    vector<string> restoreIpAddresses(string s) {
        size = s.size();
        backtrack(s, 0, 0);
        return solution;
    }
};

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SL_World

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值