You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

102 lines
3.5 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package class_2023_03_2_week;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeSet;
// 如果你熟悉 Shell 编程,那么一定了解过花括号展开,它可以用来生成任意字符串。
// 花括号展开的表达式可以看作一个由 花括号、逗号 和 小写英文字母 组成的字符串
// 定义下面几条语法规则:
// 如果只给出单一的元素 x那么表达式表示的字符串就只有 "x"。R(x) = {x}
// 例如,表达式 "a" 表示字符串 "a"。
// 而表达式 "w" 就表示字符串 "w"。
// 当两个或多个表达式并列,以逗号分隔,我们取这些表达式中元素的并集
// R({e_1,e_2,...}) = R(e_1) R(e_2) ...
// 例如,表达式 "{a,b,c}" 表示字符串 "a","b","c"。
// 而表达式 "{{a,b},{b,c}}" 也可以表示字符串 "a","b","c"。
// 要是两个或多个表达式相接,中间没有隔开时,
// 我们从这些表达式中各取一个元素依次连接形成字符串
// R(e_1 + e_2) = {a + b for (a, b) in R(e_1) × R(e_2)}
// 例如,表达式 "{a,b}{c,d}" 表示字符串 "ac","ad","bc","bd"。
// 表达式之间允许嵌套,单一元素与表达式的连接也是允许的。
// 例如,表达式 "a{b,c,d}" 表示字符串 "ab","ac","ad"​​​​​​。
// 例如,表达式 "a{b,c}{d,e}f{g,h}"
// 可以表示字符串 :
// "abdfg", "abdfh", "abefg", "abefh",
// "acdfg", "acdfh", "acefg", "acefh"。
// 给出表示基于给定语法规则的表达式 expression
// 返回它所表示的所有字符串组成的有序列表。
// 测试链接 : https://leetcode.cn/problems/brace-expansion-ii/
public class Code05_BraceExpansionII {
public static List<String> braceExpansionII(String expression) {
return new ArrayList<>(process(expression.toCharArray(), 0).ans);
}
public static class Info {
public TreeSet<String> ans;
public int end;
public Info(TreeSet<String> a, int e) {
ans = a;
end = e;
}
}
// exp[start..........] 遇到我的} 或者exp终止位置
public static Info process(char[] exp, int start) {
// 最终的结果,返回
TreeSet<String> ans = new TreeSet<>();
// 集合A X 集合B X 集合C , 遇到, parts清空
// ................ 遇到, parts清空
// 每一回的结果加入到ans
List<TreeSet<String>> parts = new ArrayList<>();
// 收集字符
StringBuilder builder = new StringBuilder();
while (start != exp.length && exp[start] != '}') {
if (exp[start] == '{') {
addStringToParts(builder, parts);
Info next = process(exp, start + 1);
parts.add(next.ans);
start = next.end + 1;
} else if (exp[start] == ',') {
addStringToParts(builder, parts);
addPartsToSet(ans, parts);
start++;
parts.clear();
} else { // 遇到英文字母
builder.append(exp[start]);
start++;
}
}
addStringToParts(builder, parts);
addPartsToSet(ans, parts);
return new Info(ans, start);
}
public static void addStringToParts(StringBuilder builder, List<TreeSet<String>> parts) {
if (builder.length() != 0) {
parts.add(new TreeSet<>());
parts.get(parts.size() - 1).add(builder.toString());
builder.delete(0, builder.length());
}
}
public static void addPartsToSet(TreeSet<String> ans, List<TreeSet<String>> parts) {
process(parts, 0, "", ans);
}
public static void process(List<TreeSet<String>> list, int i, String path, TreeSet<String> ans) {
if (i == list.size()) {
if (!path.equals("")) {
ans.add(path);
}
} else {
for (String cur : list.get(i)) {
process(list, i + 1, path + cur, ans);
}
}
}
}