0
点赞
收藏
分享

微信扫一扫

leetcode 93. 复原IP地址 思考分析

题目

给定一个只包含数字的字符串,复原它并返回所有可能的 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 地址。
leetcode 93. 复原IP地址 思考分析_子串
leetcode 93. 复原IP地址 思考分析_子串_02

思考

这一题和leetcode 131. 分割回文串 思考分析​很像,都属于利用回溯法分割字符串,所以解法上具有一定相似性。
回溯终止条件
如果逗号已经插入了3次了,观察最后一次插入往后的位置,观察剩下来的字符串能否构成合法字符串。
如果能构成,那么将s装入结果;
如果不能构成,回溯到上一个阶段。

//如果逗号数量为3,判断第四个子区间是否合法,如果合法就放入结果中
if(point_nums==3)
{
if(isValid(s,startindex,s.size()-1))
{
result.push_back(s);
}
return;
}

回溯逻辑
1、这里利用逗号来进行分割,在原string上进行操作。如果startindex~i之间的字符串合法的话,我们就在i后面插入一个逗号。
然后对逗号后面的字符串进行回溯遍历。不满足的回溯组合将把逗号消除,完成回撤。

for(int i=startindex;i<s.size();i++)
{
//子串区间:[startindex,i]
if(isValid(s,startindex,i)) //判断子串区间的子串是否合法
{
s.insert(s.begin()+i+1,'.'); //在i后面插入一个逗号
point_nums++;
backtracking(s,i+2); //切割过的字符不能再次被切割,插入逗号之后下一个子串的起始位置发生往后移动1
//回溯撤销
point_nums--;
s.erase(s.begin()+i+1); //回溯删除逗号
}
//不合法的子串直接结束本层循环,只要一个子串不合法,结果就是不合法的
else break;
}

2、考察字符串是否合法:

//判断字符串s[start,end]组成的数字是否合法
bool isValid(const string& s,int start,int end)
{
if(start>end) return false;
if(s[start]=='0' && start!=end) //0开头的数字不合法
{
return false;
}
int num=0;
for(int i=start;i<=end;i++)
{
if(s[i]>'9' ||s[i]<'0')//遇到非数字字符不合法
{
return false;
}
num =num*10+(s[i]-'0');
if(num>255) return false;
}
return true;
}

完整代码

class Solution {
public:
vector<string> result;
int point_nums=0;
//判断字符串s[start,end]组成的数字是否合法
bool isValid(const string& s,int start,int end)
{
if(start>end) return false;
if(s[start]=='0' && start!=end) //0开头的数字不合法
{
return false;
}
int num=0;
for(int i=start;i<=end;i++)
{
if(s[i]>'9' ||s[i]<'0')//遇到非数字字符不合法
{
return false;
}
num =num*10+(s[i]-'0');
if(num>255) return false;
}
return true;
}
//这里直接对s进行修改
void backtracking(string& s,int startindex)
{
//如果逗号数量为3,判断第四个子区间是否合法,如果合法就放入结果中
if(point_nums==3)
{
if(isValid(s,startindex,s.size()-1))
{
result.push_back(s);
}
return;
}
for(int i=startindex;i<s.size();i++)
{
//子串区间:[startindex,i]
if(isValid(s,startindex,i)) //判断子串区间的子串是否合法
{
s.insert(s.begin()+i+1,'.'); //在i后面插入一个逗号
point_nums++;
backtracking(s,i+2); //切割过的字符不能再次被切割,插入逗号之后下一个子串的起始位置发生往后移动1
//回溯撤销
point_nums--;
s.erase(s.begin()+i+1); //回溯删除逗号
}
//不合法的子串直接结束本层循环,只要一个子串不合法,结果就是不合法的
else break;
}
}
vector<string> restoreIpAddresses(string s) {
result.clear();
point_nums=0;
backtracking(s,0);
return result;
}
};


举报

相关推荐

0 条评论