前言
“这是我参与8月更文挑战的第18天,活动详情查看:8月更文挑战”
- NC20 数字字符串转化成IP地址(中等)
- NC26 括号生成(中等)
数字字符串转化成IP地址
描述: 现在有一个只包含数字的字符串,将该字符串转化成IP地址的形式,返回所有可能的情况。
例如:
给出的字符串为"25525522135",
返回["255.255.22.135", "255.255.221.35"]. (顺序没有关系)
思路分析: 回溯
- 已经做出的选择(记录在 temp 中)
- 结束条件((字符串遍历结束 && temp 集合的大小为4) || 字符串遍历结束 || temp 集合的大小大于4)
- 可以做出的选择(ip 地址的每一段都是 大于 0 小于等于 255 ,所以从 index 向后尝试截取 长度为 1到3 的字符串判断)
有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0)
AC 代码:
List<List<String>> res = new ArrayList<>();
public ArrayList<String> restoreIpAddresses(String s) {
ArrayList<String> ans = new ArrayList<>();
dfs(s, 0, new ArrayList<>());
for (List<String> strings : res) {
StringBuilder sb = new StringBuilder();
for (String i : strings) {
sb.append(i).append(".");
}
ans.add(sb.substring(0, sb.length() - 1));
}
return ans;
}
void dfs(String s, int index, List<String> temp) {
// 结束条件
if (index == s.length() && temp.size() == 4) {
res.add(new ArrayList<>(temp));
return;
}
if (index == s.length() || temp.size() > 4) {
return;
}
for (int i = 1; i <= 3 && index + i <= s.length(); i++) {
String val = s.substring(index, index + i);
if (check(val)) {
temp.add(val);
dfs(s, index + i, temp);
temp.remove(temp.size() - 1);
}
}
}
// 有效 ip 段 判断
boolean check(String s) {
if (s.length() > 1 && s.charAt(0) == '0') {
return false;
}
int data = Integer.parseInt(s);
return data >= 0 && data <= 255;
}
括号生成
描述: 给出n对括号,请编写一个函数来生成所有的由n对括号组成的合法组合。
例如,给出n=3,解集为:
"((()))", "(()())", "(())()", "()()()", "()(())",
思路分析: 回溯
- 已经做出的选择(记录在 temp 中)
- 结束条件((需要的左括号为0 && 需要的右括号为0) || (不合法的组合: 已经做出的选择中 右括号数量大于左括号的数量 ....))
- 可以做出的选择(选择左括号 || 选择右括号)
AC 代码:
List<List<String>> res = new ArrayList<>();
public ArrayList<String> generateParenthesis(int n) {
// write code here
dfs(n, n, new ArrayList<>());
ArrayList<String> ans = new ArrayList<>();
for (List<String> strings : res) {
StringBuilder stringBuilder = new StringBuilder();
for (String s : strings) {
stringBuilder.append(s);
}
ans.add(stringBuilder.toString());
}
return ans;
}
void dfs(int leftCount, int rightCount, List<String> temp) {
if (leftCount == 0 && rightCount == 0) {
res.add(new ArrayList<>(temp));
return;
}
if (leftCount < 0 || rightCount < 0 || leftCount > rightCount) {
return;
}
temp.add("(");
dfs(leftCount - 1, rightCount, temp);
temp.remove(temp.size() - 1);
temp.add(")");
dfs(leftCount, rightCount - 1, temp);
temp.remove(temp.size() - 1);
}