leetcode题:93. 复原IP地址(中等)

本文详细解析了复原IP地址的算法实现,通过深度优先搜索(DFS)递归查找所有可能的IP地址格式,从力扣(LeetCode)93题出发,深入探讨了解题思路及代码实现。

一、题目描述:93. 复原IP地址(中等)

给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。

示例:

输入: "25525511135"
输出: ["255.255.11.135", "255.255.111.35"]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/restore-ip-addresses
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二、解题思路

dfs递归查找

1、ip地址有三个点,四个数。

1、使用一个栈stack记录ip地址的四个数中的数字第一个字母位置.通过n=0记录第ip的第n+1个数字(这里n初始化为0,为了方便,也可以初始化为1,当n

2、使用双指针left,right寻找符合要求的数字,初始化right = left+1,right循环往右移动,left到right直接的字母转成的数字再0~255之间,则left入栈到stack记录当前left的位置并且初始化left=right,进入递归寻找ip的下一个数字。递归返回的时候stack出栈,right++进入下一个循环,当rigth右移到到left,right直接的数字大于255的时候,说明后面的都不符合ip地址的数字范围,退出循环。

3、当递归到第四个数字的时候n==3的时候,则判断left往后所有字母转成数字之后是否符合ip的数字要求。如果符合,则stack入栈字符串的最后位置(s.size()),根据stack的偏移量将源字符串转成ip4的格式,保存。然后stack出栈返回。直到所有分支都递归完退出。

其中要注意的010这样的数字也不符合ip4的格式,需要做判断。

三、代码

 template <class T>
void print(T & t)
{
    for(int i = 0;i<t.size();i++)
    {
        cout<<t[i]<<",";
    }
    cout<<endl;
}
class Solution {
public:
    vector<string> restoreIpAddresses(string s) {
        vector<int> stack(1,0);
        vector<string> save;
        res(s ,0,0,stack,save);
        return save;
    }
    void res(string & s ,int left,int n,vector<int> & stack,vector<string> & save)
    {
        //print(save);
        if(n == 3)
        {
            if(left < s.size() - 4)
                return;
            string stmp = s.substr(left);
            if(stmp.size() > 1)
            {
                if(stmp[0] == '0')
                    return;
            }
            if(atoi(stmp.c_str()) <= 255)
            {
                stack.push_back(s.size());
                string out;
                for(int i = 1; i < stack.size();i++)
                {
                    
                    out.append(s.substr(stack[i-1],stack[i]-stack[i-1]));
                    if(i != stack.size()-1)
                    {
                        out.append(".");
                    }
                }
                stack.pop_back();
                save.push_back(out);
            }
            return;
        }
        int right = left + 1;
        while(right < s.size())
        {
            string stmp = s.substr(left,right-left);
            if(stmp.size() > 1)
            {
                if(stmp[0] == '0')
                    break;
            }
            int tmp = atoi(stmp.c_str());
            if( tmp > 255)
                break;
           //cout<<tmp<<endl;
            stack.push_back(right);
            res(s ,right,n + 1,stack,save);
            stack.pop_back();
            right++;
            
        }
        
    }
  
    
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值