一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第21天,点击查看活动详情。
题目描述
有效 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 中的任何数字。你可以按 任何 顺序返回答案。
思路描述
关键条件只包含数字的字符串。
在这个前提下这道题其实就是分成两部分,第一部分是分割字符串,第二部分是判断字符串的合法行。
我们可以用dfs解决这个问题
代码整体分为几部分
- 达成条件-》加入结果数组
- 达成失败 return
- 截取下一段
需要注意的是,由于不存在前导0的问题,因此遇到0就直接dfs
具体实现
void dfs(const string& s, int segId, int segStart) {
if (segId == SEG_COUNT) {
if (segStart == s.size()) {
string ipAddr;
for (int i = 0; i < SEG_COUNT; ++i) {
ipAddr += to_string(segments[i]);
if (i != SEG_COUNT - 1) {
ipAddr += ".";
}
}
ans.push_back(move(ipAddr));
}
return;
}
if (segStart == s.size()) {
return;
}
if (s[segStart] == '0') {
segments[segId] = 0;
dfs(s, segId + 1, segStart + 1);
}
int addr = 0;
for (int segEnd = segStart; segEnd < s.size(); ++segEnd) {
addr = addr * 10 + (s[segEnd] - '0');
if (addr > 0 && addr <= 0xFF) {
segments[segId] = addr;
dfs(s, segId + 1, segEnd + 1);
} else {
break;
}
}
}
总结
这道题并不一定要使用回溯,理论上写四层甚至三层for循环也可以实现(因为最后一层一定使用剩下所有的字符。)