93. 复原 IP 地址

题目出处:https://leetcode-cn.com/problems/restore-ip-addresses/

 思路:回溯+减枝解决。题目中的字符串全为数字构成,需要处理字符串为0开头的情况。

  1. 递归函数dfs(duan, startpos, oneAns):代表IP地址的第duan个字符串,duan属于{0,1,2,3};startpos代表第duan+1个字符串的首地址,oneAns代表满足题目条件的一个IP地址划分。
  2. 递归终止条件:如果duan==4&&startPos = n说明字符串中的所有字符都参与了划分,且被划分成四段,即此时找到一个满足条件的IP地址。
  3. 剪枝条件:若没遍历完字符串中的全部字符就已经找出一个IP,就提前结束搜索。
  4. 递归函数体:从字符串的首字符开始遍历,IP地址的每一段都不能超过三个字符,因此枚举以s[startpos]为首字符,长度为1,2,3的字符串,并判断字符串代表的数值是否在[0,255]中;由于IP地址的每一段都不能含有前导0,所以若s[startpos]为0,则单独为一个IP段。因此,实现过程中以s[startpos]是否为0进行两种情况的划分。
class Solution {
private:
    vector<string> ans;      
public:
    bool check(string& s){
        int s_num = atoi(s.c_str());
        if(s_num >= 0 && s_num <= 255){
            return true;
        }

        return false;
    }
    void dfs(int duan, int startPos, string &s, vector<string> &oneAns, int & n){
        if(duan == 4 && startPos == n){
            string res = "";
            for(int i = 0; i < 3; ++i){
               res += oneAns[i]+'.';
            }
            res += oneAns[3];
            ans.push_back(res);
            return;     
        }

        if(duan == 4){  //减枝,没遍历完字符串就找到了IP的四段,就提前结束搜索
            return;
        }
        
        if(s[startPos] != '0'){   //不含有前导0
            for(int len = 1; len <= 3 && startPos+len <= n; ++len){  //注意startPos+len <= n有等号
                string now_seg = s.substr(startPos, len);
                if(check(now_seg)){
                    oneAns.push_back(now_seg);
                    dfs(duan+1, startPos+len, s, oneAns, n);
                    oneAns.pop_back();
                }
            }
        }
        else{   //含有前导0
            string now_seg = "";  
            now_seg.push_back(s[startPos]);  //char转换成string的方式,用push_back()
            oneAns.push_back(now_seg);
            dfs(duan+1, startPos+1, s, oneAns, n);
            oneAns.pop_back();
            now_seg.pop_back();   
        }
    }
    vector<string> restoreIpAddresses(string s) {
        int n = s.length();
        if(n <= 3){
            return ans;
        }
        int duan = 0, startPos = 0;
        vector<string> oneAns;
        dfs(duan, startPos, s, oneAns, n);

        return ans;
    }
};

//注意startPos+len <= n有等号的原因

如 s = “1111”,startpos = 1, len = 3,  s.substr(startpos, len) = “111”,此时startpos+len == 4 == s.length() = 4;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值