Leetcode 1087. Brace Expansion

这篇博客介绍了LeetCode上的第1087题—— Brace Expansion 的解题思路。文章提供了两种解法,分别是暴力递归和带记忆化的优化方法,并分析了它们的时间和空间复杂度。博主还提出了面试中可能讨论的问题,包括括号内字符串长度是否可能大于1以及生成的单词是否需要唯一。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

Description
https://leetcode.com/problems/brace-expansion/

You are given a string s representing a list of words. Each letter in the word has one or more options.

If there is one option, the letter is represented as is.
If there is more than one option, then curly braces delimit the options. For example, “{a,b,c}” represents options [“a”, “b”, “c”].
For example, if s = “a{b,c}”, the first character is always ‘a’, but the second character can be ‘b’ or ‘c’. The original list is [“ab”, “ac”].

Return all words that can be formed in this manner, sorted in lexicographical order.

Example 1:
Input: s = “{a,b}c{d,e}f”
Output: [“acdf”,“acef”,“bcdf”,“bcef”]

Example 2:
Input: s = “abcd”
Output: [“abcd”]
Constraints:

1 <= s.length <= 50
s consists of curly brackets ‘{}’, commas ‘,’, and lowercase English letters.
s is guaranteed to be a valid input.
There are no nested curly brackets.
All characters inside a pair of consecutive opening and ending curly brackets are different.

题目被锁了,只能自己开个ide写的

解法1:暴力recursion

暴力解法无需复杂的返回值,只需传引用,在最后expand答案即可

void expand(string s,vector<string>& ans,string curr){
    if(s.size() == 0) {
        ans.push_back(curr);
        return;
    }
    int i = 0;
    if(s[i] == '{'){
        string tmp = "";
        vector<string> tmp_vec;
        while(s[i] != '}'){
            if(s[i] >= 'a' && s[i] <= 'z'){
                tmp = tmp + s[i];
            }else if(s[i] == ','){
                tmp_vec.push_back(tmp);
                tmp = "";
            }
            i++;
        }
        tmp_vec.push_back(tmp);
        for(auto& t : tmp_vec){
            expand(s.substr(i+1),ans,curr+t);
        }
    }else{
        expand(s.substr(i+1),ans,curr+s[i]);
    }
    return;
}
int main()
{
    
    string s = "{a,b}c{d,e}f";
    string s = "abcd";
    string s = "{ab,cd}{ef,jh}i{j,k}";
    vector<string> ans;
    expand(s,ans,"");
    for(auto& el : ans){
        cout << el << endl;
    }
    // will a single element inside {} with lenth larger than 1?
    // if the formed words need to be unique
    return 0;
}

时间复杂度:O(n^m),n为括号内元素的平均个数,m为括号的数量
空间复杂度:O(m)
不是特别确定这个时间复杂度对不对

解法2:

使用返回值并添加memorization,这种写法就比较麻烦,但是会快很多

#include <iostream>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <stack>
#include <queue>

using namespace std;

vector<string> helper(string s,unordered_map<string,vector<string>>& memo){
    if(s.size() == 0) return {""};
    if(memo.count(s)) return memo[s];
    string ans = "";
    vector<string> ans_vec;
    bool found = false;
    for(int i=0;i<s.size();i++){
        if(s[i] >= 'a' && s[i] <= 'z'){
            ans = ans + s[i];
        }else if(s[i] == '{'){
            found = true;
            string tmp = "";
            vector<string> tmp_vec;
            while(s[i] != '}'){
                if(s[i] >= 'a' && s[i] <= 'z'){
                    tmp = tmp + s[i];
                }else if(s[i] == ','){
                    tmp_vec.push_back(tmp);
                    // cout << tmp << endl;
                    tmp = "";
                }
                
                // cout << tmp << endl;
                i++;
            }
            tmp_vec.push_back(tmp);
            // cout << tmp_vec.size() << endl;
            vector<string> sub_vec = helper(s.substr(i+1),memo);
            for(auto& t:tmp_vec){
                for(auto& sub:sub_vec){
                    ans_vec.push_back(ans+t+sub);
                }
            }
            break;
        }
    }
    if(!found) ans_vec.push_back(ans);
    memo[s] = ans_vec;
    return memo[s];
}

vector<string> expand(string s){
    unordered_map<string,vector<string>> memo;
    return helper(s,memo);
}
int main()
{
    
    string s = "{a,b}c{d,e}f";
    // string s = "abcd";
    // string s = "{ab,cd}{ef,jh}i{j,k}";
    vector<string> ans = expand(s);
    cout << ans.size() << endl;
    for(auto& el : ans){
        cout << el << endl;
    }
   
    // will a single element inside {} with lenth larger than 1?
    // if the formed words need to be unique
    return 0;
}

时间复杂度:O(n),n字符串长度
空间复杂度:O(m)
不是特别确定这个时间复杂度对不对

good question to ask during interview

  • will a single element inside {} with lenth larger than 1? (我这边的写法是假设括号内用逗号分割开的字符串长度有可能大于1)
  • if the formed words need to be unique? 按照题目的意思,每个括号的字符不相同的话,那么产生的答案肯定是唯一的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值