93. 复原IP地址

在这里插入图片描述
十道回溯剪枝就这一道难的,感觉重回pat那时候的字符串大模拟,不过确实是好题。
用一个vector来存每个字段的数字即可,这样可以在最后在进行IP地质的拼接。
这道题最重要的就是剪枝。递归边界就是tmp.size()==4了,如果s用完了,就将tmp数组里的字符串拼接成IP地址即可。然后不管是否用完s,都要return了。
从当前位开始最多往后取3位,从1遍历到3。此时第一个剪枝操作:如果当前起始字符+要截取的字符长度越界了,直接return。第二个剪枝操作:截取的这一字段的字符串对应的数字大于255也return。第三个剪枝操作:最重要的前导0,如果当前不是截取当前位的第一个数字,也就是i>1而且当前字段的第一位为0,直接return。
将截取的字段加入tmp然后进行dfs,记得手动弹出

class Solution {
public:
    void dfs(string s, int start){
        if(tmp.size() == 4){
            if(start == s.length()){
                string str = tmp[0];
                for(int i = 1; i < tmp.size(); ++i){
                    str += "."+tmp[i];
                }
                res.push_back(str);
            }
            //如果没有用完s,直接return,如果用完s在进行完操作后也要return
            return;
        }
        //从当前位往后最多再取三位,i=1包括取的是当前的所以判断越界要注意
        for(int i = 1; i <= 3; ++i){
            //start+i==length是被允许的
            if(start + i - 1 >= s.length()) return;

            //如果当前截取的字符串大小大于255也return
            if(stoi(s.substr(start,i)) > 255) return;

            //如果当前有前导0的也直接return
            //也就是第一位是0,而且现在进行到第一位之后了,证明你企图截取01,012这种
            if(s[start] == '0' && i != 1) return;

            //如果上面的都不满足,就证明是一个合格的字节
            tmp.push_back(s.substr(start,i));
            dfs(s,start+i);
            tmp.pop_back();//这一步回溯很重要,你想要没有这一步,就把tmp作为变量来传递,会自动pop_back
        }
    }
    vector<string> restoreIpAddresses(string s) {
        //dfs+回溯,用一个vector来存当前组成IP地址的字段,当等于4且s用完了,就补上中间的.号然后加入res中
        if(s.length() < 4 || s.length() > 12) return res;
        dfs(s,0);
        return res;
    }
private:
    vector<string> res;
    vector<string> tmp;
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值