LeetCode 1087. 花括号展开

1087. 花括号展开

给定一个表示单词列表的字符串 s 。单词中的每个字母都有一个或多个选项。

  • 如果有一个选项,则字母按原样表示。
  • 如果有多个选项,则用大括号分隔选项。例如,  "{a,b,c}"  表示选项  ["a", "b", "c"]  。

例如,如果  s = "a{b,c}"  ,第一个字符总是 'a' ,但第二个字符可以是 'b' 或 'c' 。原来的列表是 ["ab", "ac"] 。

请你 按字典顺序 ,返回所有以这种方式形成的单词。

示例 1:

输入:s = "{a,b}c{d,e}f"
输出:["acdf","acef","bcdf","bcef"]

示例 2:

输入:s = "abcd"
输出:["abcd"]

提示:

  • 1 <= S.length <= 50
  • s 由括号 '{}' , ',' 和小写英文字母组成。
  • s 保证是一个有效的输入。
  • 没有嵌套的大括号。
  • 在一对连续的左括号和右括号内的所有字符都是不同的。

提示 1

All generated strings are of the same size. How can we generate all of these strings?


提示 2

Do a backtracking on which each level of it has to choose one single (e.g. 'a') character or any character of the given parenthesized group (e.g. "{a,b,c}")

解法1:回溯法

算法逻辑

  • 初始化一个结果列表 result 来存储所有可能的单词组合。
  • 使用一个辅助函数 backtrack 来实现回溯逻辑。这个函数接收当前索引 index,当前构建的单词 current,以及结果列表 result
  • 如果当前索引等于字符串长度,说明已经处理完所有字符,将当前构建的单词添加到结果列表中,并返回。
  • 如果当前字符是 {,说明遇到了一个字符组。找到对应的 },并获取这个字符组内的所有选项。
  • 对于每个选项,将其添加到当前构建的单词中,然后递归调用 backtrack 函数,继续处理下一个字符。
  • 如果当前字符不是 {,直接将其添加到当前构建的单词中,然后递归调用 backtrack 函数,继续处理下一个字符。
  • 在递归调用结束后,需要将当前字符从构建的单词中移除,以便回退到上一步,尝试其他选项。

Java版:

class Solution {
    public String[] expand(String s) {
        List<String> result = new ArrayList<>();
        backtrack(s, 0, new StringBuffer(), result);
        Collections.sort(result);
        return result.toArray(new String[0]);
    }

    private void backtrack(String s, int index, StringBuffer current, List<String> result) {
        if (index == s.length()) {
            result.add(current.toString());
            return;
        }

        char ch = s.charAt(index);
        if (ch == '{') {
            int end = s.indexOf("}", index);
            String[] choices = s.substring(index + 1, end).split(",");
            for (String choice : choices) {
                current.append(choice);
                backtrack(s, end + 1, current, result);
                current.deleteCharAt(current.length() - 1);
            }
        } else {
            current.append(ch);
            backtrack(s, index + 1, current, result);
            current.deleteCharAt(current.length() - 1);
        }
    }
}

Python3版:

class Solution:
    def expand(self, s: str) -> List[str]:
        def backtrack(index, current, result):
            if index == len(s):
                result.append(current)
                return 
            
            if s[index] == '{':
                end = s.find("}", index)
                choices = s[index + 1 : end].split(",")
                for choice in choices:
                    current += choice
                    backtrack(end + 1, current, result)
                    current = current[:-1]
            else:
                current += s[index]
                backtrack(index + 1, current, result)
                current = current[:-1]


        result = []
        backtrack(0, '', result)
        result.sort()
        return result

解法2: 栈扩展法

这种解法使用栈来存储当前的构建状态,并在遇到字符组时扩展栈中的元素,这种方法在处理过程中对字符组进行展开,类似于树的遍历。

class Solution:
    def expand(self, s: str) -> List[str]:
        stack = []
        i = 0
        while i < len(s):
            if s[i] == '{':
                j = s.find('}', i)
                choices = s[i + 1 : j].split(',')
                if stack:
                    temp = []
                    for c in choices:
                        temp.extend([item + c for item in stack])
                    stack = temp
                else:
                    stack = [c for c in choices]
                i = j
            else:
                if stack:
                    stack = [item + s[i] for item in stack] 
                else: 
                    stack.append(s[i])
            i += 1
        stack.sort()
        return stack

复杂度分析

  • 时间复杂度:O(n ^ 2)。由于我们需要生成所有可能的组合,最坏情况下,每个字符都可能是一个字符组,包含 n 个选项,因此时间复杂度为O(n ^ 2),其中 n 是字符串 s 的长度。
  • 空间复杂度:O(n)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值