1.题目要求
有效 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();
}
}
};