leetcode 93. 复原 IP 地址 [回溯]

1.题目要求

leetcode 93. 复原 IP 地址

有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 ‘.’ 分隔。

例如:“0.1.2.201” 和 “192.168.1.1” 是 有效 IP 地址,但是 “0.011.255.245”、“192.168.1.312” 和 “192.168@1.1” 是 无效 IP 地址。
给定一个只包含数字的字符串 s ,用以表示一个 IP 地址,返回所有可能的有效 IP 地址,这些地址可以通过在 s 中插入 ‘.’ 来形成。你不能重新排序或删除 s 中的任何数字。你可以按 任何顺序 返回答案。

示例 1:

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

示例 2:

输入:s = "0000"
输出:["0.0.0.0"]

示例 3:

输入:s = "1111"
输出:["1.1.1.1"]

示例 4:

输入:s = "010010"
输出:["0.10.0.10","0.100.1.0"]

示例 5:

输入:s = "101023"
输出:["1.0.10.23","1.0.102.3","10.1.0.23","10.10.2.3","101.0.2.3"]

提示:

0 <= s.length <= 20
s 仅由数字组成

2.解题思路(回溯算法实现)

实现算法:回溯
本题思路如下:

由于回溯算法属于在一个范围内找到所有符合条件的解,穷举每一种情况,将符合条件的解返回。
故本题采用回溯算法实现。

1、设立两个字符串数组,res[] 用于保存结果, cur[] 用于记录穷举过程中的ip各字段

cur[0] ~ ip地址的第1个字段
cur[1] ~ ip地址的第2个字段
cur[2] ~ ip地址的第3个字段
cur[3] ~ ip地址的第4个字段

2、回溯函数 backtrack()需要根据传入的当前指针位置index,由于0-255最多只有三位数,
所以只需要判断从index-index+0(即当前这一位);
indexindex+1; index-index+2; …;index+index+i-1 这i个位的数即可。

比如: ip地址为255 index=0
则需要穷举2、25、255这三种情况。

(1)首先指针index从下标0开始。
(2)回溯终止的条件是cur[]中已经存了ip的4个字段,如果这时 指针index也正好已经走完全部字符串,说明这是一种合法的ip地址,把4个字段拼接后存到res中。

(3)如果当前cur中还不够4个字段,就从当前指针位置,依次往后添加一个字符,两个字符,三个字符,继续回溯满足的情况。
(4)如当前指针指向’0’,判断下是否为前导0,是则跳过;判断下是否超出255,是则跳过。
(5)添加符合的字段到cur[],下一次回溯从下标index+i开始;
(6)回溯结束后,将当前字段取出,以准备添加下一个合法字段。

3.C++代码实现

class Solution {
public:
    vector<string> restoreIpAddresses(string s) {

            vector<string> res; //结果数组
            vector<string> cur; //中间数组
            if(s.size()==0)  return res;

            backtrack(s,0,cur,res);     //回溯
            return res;
    }
    
    void backtrack(string s, int index, vector<string>&cur, vector<string>&res ){
                               //index:当前指针位置
            if( cur.size()==4 ){

                if( index==s.size() )//指针已指到字符串结尾
                {
                    string ip = cur[0] + '.' + cur[1] + '.' + cur[2] + '.' + cur[3];  
                    res.push_back(ip);
                }
                return ;
            }
            //中间数组不够4个字符串
            for(int i=1;i<=3;i++) //每个整数位范围0-255  最多3位数 从1位开始穷举,直到3位数
            { 
                if( index + i > s.size() )	//超出工作范围
                    break;
                string str = s.substr(index,i);// 从下标index,取出i个字符

                if( (str[0]=='0' && str.size()>1) || stoi(str)>255 )// 不合法数字 03、033、256... 
                    continue;
                
                cur.push_back(str);
                backtrack(s, index+i, cur, res);  //下一次指针从index+i开始
                cur.pop_back();
            }

    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值