Restore IP Addresses

Given a string containing only digits, restore it by returning all possible valid IP address combinations.

For example:
Given "25525511135",

return ["255.255.11.135", "255.255.111.35"]. (Order does not matter)

不能出现:1.01.1.1的含有前缀0的情况!代码中有处理

此题使用回溯法。(枚举+剪枝)

要充分理解递归树!

 vector<string> restoreIpAddresses(string s) {
     string ip;
     vector<string> result;
     dfs_IpAddresses(s,0,0,ip,result);
     return result;
    }
    
    void dfs_IpAddresses(string s,int start,int step,string ip,vector<string> &result)
    {
        
        if(step >= 4 && start == s.size())
        {
            //去除最后一个字符点号(.)
            ip.erase(ip.size()-1);//会多加一个'.',所以的去掉!
            result.push_back(ip);
            return;
        }
        else
        {
            int num = 0;
            //减枝函数-一个最小,一个最大剩余字符数!
            if((s.size() - start ) < (4 - step)) return ;//剩余字符不能少于ip中每个位一位字符
            if((s.size() - start ) > 3*(4 - step))return ;//剩余字符最多不多于ip中每个位3位字符
            
            for(int i = 0; i < 3;i++)
            {
               num = num*10 + ( s[start + i] - '0' );//用于判断是否大于最大数255!
               
               if(num > 255)continue;
               //此处ip为需要变动加入到ip 中为递归树同层兄弟节点使用!
               ip = ip+s[start + i];//个人由于没注意:此次之前写错了,直接全由dfs_IpAddresses处理而出错!(同层需使用所以放在外层处理!)
               //不能在此处处理含有前缀为0的!//此次已处理当前整体为0,可能被去掉!
               //此处ip+'.'//为当前路径加入'.',为虚的不影响同层兄弟节点使用ip。
               dfs_IpAddresses(s,start+i+1,step+1,ip+'.',result);//处理ip地址!
               if(num == 0) return ; //当前层全不要!不能有前缀为0的。如上面提到!
            }
        }
    }
第二次
vector<string> restoreIpAddresses(string s)
    {
    	if (s.size() < 3)
    	{
    		return vector<string>();
    	}
     
    	vector<string> res;
    	string res_one;
    	restore_ip(s,0,0,res,res_one);
    	return res;
    }

    void restore_ip(string &str,int level,int pos,vector<string> &res,string res_one)
    {
    	if (level >= 4)//ip最多4个
    	{
    		if (pos == str.size())//只有长度刚好才取,否则重复
    		{
    			res.push_back(res_one.substr(0,res_one.size()-1));
    			
    		}
    		 
    		return ;
    	}
    	
    	int num = 0;
    	for (int i = pos;i < pos+3;i++)//枚举长度 1 - 3
    	{
    		if (i >= str.size())//检查是否长度太短
    		{
    			return ;
    		}
    
    		num = num*10 + str[i] - '0';
    		if ( num > 255)//处理数字大于255的,ip地址固有限制
    		{
    			return ;
    		}
                if (i-pos >= 1 &&str[pos] == '0')//处理0为前缀的情况!!
    		{
    			return;
    		}
    		restore_ip(str,level+1,i+1,res,res_one+str.substr(pos,i-pos+1)+'.');
    
    	}
    }


不处理前缀0的情况,以下是处理的代码。

//需注意001 ,01 需去掉 ,而0,10,100需保存,故而其实只需判断第一个为0的情况,但是还有一种为0但不能去掉,所以长度>=2 才处理判断!

if (i-pos >= 1 &&str[pos] == '0') 
{
return;

}

大家把以上这部分代码注释会出现如下错误:

Input:"010010"
Output:["0.1.0.010","0.1.00.10","0.1.001.0","0.10.0.10","0.10.01.0","0.100.1.0","01.0.0.10","01.0.01.0","01.00.1.0","010.0.1.0"]
Expected:["0.10.0.10","0.100.1.0"]

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值