DFS-lintcode恢复ip地址(Restore IP Addresses)

典型的DFS找满足条件的所有可行解。ip地址由4部分组成,每部分范围为0-255,容易忽略的是:每部分中0是可行的,但多个连续0如192.168.000.1是非法的,192.168.001.1这样前面有多余0的也是非法的,关键在于如何将这些条件转化为深搜中的条件

不熟悉深搜的可以先看看求排列组合的深搜题:DFS求全排列        DFS求组合

分析样例,第一部分的所有可能为2,25,255,若第一部分为2,则问题转化为将后续的5525511135分为3部分....以此类推,借助一个图来分析:


图中只画了一部分,首先我们将2看成第一部分,那么第二部分就有5,52,525这3中情况,525超过了255,不符合;若第二部分为5,则继续往下推又有3种........到这里我们已经可以归纳出搜索的思路:

start初值为0,我们每次处理的字符串为[start,n-1],循环i,i的范围为[start,start+2],遍历出3种可能,判断是否合法,start到达n即结束

还需要设置一个step,初值为0,表示当前正处理的ip地址的第step部分,step值为4的时候表示0,1,2,3部分已找出,结束

处理第step部分时(第step还未确定),还剩下4-step没确定,故剩下的字符串长度的范围为[4-step,(4-step)*3]

分析到这里代码已经基本成型

class Solution {
public:
    /*
     * @param s: the IP string
     * @return: All possible valid IP addresses
     */
    vector<string> restoreIpAddresses(string &s) {
        // write your code here
        vector<string> res;
        string tmp;
        DFS(s,res,tmp,0,0);
        return res;
    }
    void DFS(string& s,vector<string>& res,string tmp,int start,int step){
        //收敛条件
        if(start==s.size() && step==4){
            tmp.resize(tmp.size()-1);//去除最后一个.
            res.push_back(tmp);
            return;
        }
        //根据长度进行剪枝
        if(s.size()-start>(4-step)*3) return;
        if(s.size()-start<(4-step)) return;
        int num=0;
        //状态的扩展
        for(int i=start;i<start+3;++i){
            num=num*10+(s[i]-'0');
            if(num<=255){//合法
                tmp+=s[i];
                DFS(s,res,tmp+'.',i+1,step+1);
            }
            if(num==0) break;
        }
    }
};
还剩一个问题,这样写为什么允许了单个0而排除了连续0?

只用了if(num==0) break;这一条语句,要执行这条语句,必须要从上面的DFS递归中返回

若当前为单个0,则满足<=255,进入递归,递归返回后,表示这部分为单个0的所有可能已经处理完了

若向后循环,则可能出现这一部分为连续0,0后跟数字(000,001)这些都不能作为IP地址4部分的1部分,故直接break就好

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值