我们用一个特殊的字符串 S
来表示一份单词列表,之所以能展开成为一个列表,是因为这个字符串 S
中存在一个叫做「选项」的概念:
单词中的每个字母可能只有一个选项或存在多个备选项。如果只有一个选项,那么该字母按原样表示。
如果存在多个选项,就会以花括号包裹来表示这些选项(使它们与其他字母分隔开),例如 "{a,b,c}"
表示 ["a", "b", "c"]
。
例子:"{a,b,c}d{e,f}"
可以表示单词列表 ["ade", "adf", "bde", "bdf", "cde", "cdf"]
。
请你按字典顺序,返回所有以这种方式形成的单词。
示例 1:
输入:"{a,b}c{d,e}f" 输出:["acdf","acef","bcdf","bcef"]
示例 2:
输入:"abcd" 输出:["abcd"]
提示:
1 <= S.length <= 50
- 你可以假设题目中不存在嵌套的花括号
- 在一对连续的花括号(开花括号与闭花括号)之间的所有字母都不会相同
先将字符串 s 进行 convert 转换,比如 "{a,b}{z,x,y}"
转换为 [['a', 'b'], ['z', 'x', 'y']]
,然后利用 DFS 回溯获取每一个单词,放到 ans 中,最后对 ans 进行排序并返回即可。
class Solution:
def expand(self, s: str) -> List[str]:
def convert(s):
if not s:
return
if s[0] == '{':
j = s.find('}')
items.append(s[1: j].split(','))
convert(s[j + 1:])
else:
j = s.find('{')
if j != -1:
items.append(s[: j].split(','))
convert(s[j:])
else:
items.append(s.split(','))
def dfs(i, t):
if i == len(items):
ans.append(''.join(t))
return
for c in items[i]:
t.append(c)
dfs(i + 1, t)
t.pop()
items = []
convert(s)
ans = []
dfs(0, [])
ans.sort()
return ans
class Solution {
private List<String> ans;
private List<String[]> items;
public String[] expand(String s) {
ans = new ArrayList<>();
items = new ArrayList<>();
convert(s);
dfs(0, new ArrayList<>());
Collections.sort(ans);
return ans.toArray(new String[0]);
}
private void convert(String s) {
if ("".equals(s)) {
return;
}
if (s.charAt(0) == '{') {
int j = s.indexOf("}");
items.add(s.substring(1, j).split(","));
convert(s.substring(j + 1));
} else {
int j = s.indexOf("{");
if (j != -1) {
items.add(s.substring(0, j).split(","));
convert(s.substring(j));
} else {
items.add(s.split(","));
}
}
}
private void dfs(int i, List<String> t) {
if (i == items.size()) {
ans.add(String.join("", t));
return;
}
for (String c : items.get(i)) {
t.add(c);
dfs(i + 1, t);
t.remove(t.size() - 1);
}
}
}