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 中的任何数字。你可以按 任何 顺序返回答案。
示例
输入: s = "25525511135"
输出: ["255.255.11.135","255.255.111.35"]
解题思路
比较简单的回溯,重点是剪枝细节比较多。
- 字符串长度小于4或者大于12 不可能得到合法的ip地址。
- 当前part小于最小长度限制(不回溯,continue)
- 非0值存在前导0剪枝
- 多个0组成的0值剪枝
- 当前part超过最大值剪枝
完整代码:
class Solution {
List<String> res;
StringBuilder path;
public List<String> restoreIpAddresses(String s) {
int n = s.length();
if (n < 4 || n > 12) return new ArrayList<>();
res = new ArrayList<>();
path = new StringBuilder();
backtrack(s, 0, 0);
return res;
}
void backtrack(String s, int start, int parts) {
if (parts >= 4) {
res.add(path.toString());
}
int n = s.length();
char[] cs = s.toCharArray();
for (int i = start; i < n; i++) {
if (parts == 3) i = n - 1;
int subLen = i - start + 1;
String sub = s.substring(start, i + 1);
if (subLen < n - path.length() + parts - 3 * (3 - parts)) continue;
int num = Integer.parseInt(sub);
if (0 != num && sub.charAt(0) == '0') return;
if (0 == num && subLen > 1) return;
if (num > 255) return;
int pre = path.length();
path.append(sub);
if (parts < 3) path.append('.');
backtrack(s, i + 1, parts + 1);
path.delete(pre, path.length());
}
}
}