花括号展开
难度:
标签:
题目描述
代码结果
运行时间: 26 ms, 内存: 16.5 MB
/*
* Leetcode题目: 花括号展开
* 题目思路:
* 1. 使用递归方法解析输入字符串。
* 2. 在递归过程中,如果遇到花括号,首先解析内部内容并返回结果。
* 3. 解析后的结果使用回溯法生成所有可能的组合。
* 4. 最终将所有结果按字典序排序。
* 5. 使用Java Stream进行组合和排序。
*/
import java.util.*;
import java.util.stream.*;
public class BraceExpansionStream {
public List<String> expand(String s) {
if (s.isEmpty()) return Collections.emptyList();
List<String> result = helper(s, 0);
return result.stream().sorted().collect(Collectors.toList());
}
private List<String> helper(String s, int index) {
if (index == s.length()) return Arrays.asList("");
List<String> result = new ArrayList<>();
if (s.charAt(index) == '{') {
int closeIndex = s.indexOf('}', index);
String[] options = s.substring(index + 1, closeIndex).split(",");
List<String> suffixes = helper(s, closeIndex + 1);
for (String option : options) {
result.addAll(suffixes.stream().map(suffix -> option + suffix).collect(Collectors.toList()));
}
} else {
result = helper(s, index + 1).stream().map(suffix -> s.charAt(index) + suffix).collect(Collectors.toList());
}
return result;
}
public static void main(String[] args) {
BraceExpansionStream solution = new BraceExpansionStream();
System.out.println(solution.expand("{a,b}c{d,e}f"));
}
}
解释
方法:
该题解采用了深度优先搜索(DFS)来解决花括号展开问题。首先,遍历输入字符串,按照花括号内外的字符分组,并存储到数组arr中。数组中的每个元素要么是花括号内的一组字符,要么是花括号外的单个字符。利用DFS遍历arr数组中的每个元素,构建所有可能的字符串组合。最后,返回排序后的结果列表。
时间复杂度:
O(n * k^n)
空间复杂度:
O(n + k^n)
代码细节讲解
🦆
在处理花括号展开问题中,为什么选择使用深度优先搜索(DFS)而不是其他算法如广度优先搜索(BFS)或迭代方法?
▷🦆
题解中提到,数组arr中的每个元素要么是花括号内的一组字符,要么是花括号外的单个字符。如何处理连续的花括号外字符,例如在字符串`s = 'ab{c,d}e{f,g}h'`中的`ab`和`e`?
▷🦆
在DFS递归函数中,如果某个位置的字符集包含多个字符,如何确保所有字符都被遍历且没有遗漏?
▷🦆
递归过程中是否有可能出现栈溢出的情况?如果有,是在什么样的输入条件下可能发生?
▷相关问题
字符串解码
给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: k[encoded_string]
,表示其中方括号内部的 encoded_string
正好重复 k
次。注意 k
保证为正整数。
你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k
,例如不会出现像 3a
或 2[4]
的输入。
示例 1:
输入:s = "3[a]2[bc]" 输出:"aaabcbc"
示例 2:
输入:s = "3[a2[c]]" 输出:"accaccacc"
示例 3:
输入:s = "2[abc]3[cd]ef" 输出:"abcabccdcdcdef"
示例 4:
输入:s = "abc3[cd]xyz" 输出:"abccdcdcdxyz"
提示:
1 <= s.length <= 30
s
由小写英文字母、数字和方括号'[]'
组成s
保证是一个 有效 的输入。s
中所有整数的取值范围为[1, 300]
字母大小写全排列
给定一个字符串 s
,通过将字符串 s
中的每个字母转变大小写,我们可以获得一个新的字符串。
返回 所有可能得到的字符串集合 。以 任意顺序 返回输出。
示例 1:
输入:s = "a1b2" 输出:["a1b2", "a1B2", "A1b2", "A1B2"]
示例 2:
输入: s = "3z4" 输出: ["3z4","3Z4"]
提示:
1 <= s.length <= 12
s
由小写英文字母、大写英文字母和数字组成
花括号展开 II
如果你熟悉 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
,返回它所表示的所有字符串组成的有序列表。
假如你希望以「集合」的概念了解此题,也可以通过点击 “显示英文描述” 获取详情。
示例 1:
输入:expression = "{a,b}{c,{d,e}}" 输出:["ac","ad","ae","bc","bd","be"]
示例 2:
输入:expression = "{{a,z},a{b,c},{ab,z}}" 输出:["a","ab","ac","z"] 解释:输出中 不应 出现重复的组合结果。
提示:
1 <= expression.length <= 60
expression[i]
由'{'
,'}'
,','
或小写英文字母组成- 给出的表达式
expression
用以表示一组基于题目描述中语法构造的字符串