Skip to content

Latest commit

 

History

History
211 lines (168 loc) · 6.13 KB

File metadata and controls

211 lines (168 loc) · 6.13 KB

English Version

题目描述

如果你熟悉 Shell 编程,那么一定了解过花括号展开,它可以用来生成任意字符串。

花括号展开的表达式可以看作一个由 花括号逗号小写英文字母 组成的字符串,定义下面几条语法规则:

  • 如果只给出单一的元素 x,那么表达式表示的字符串就只有 "x"R(x) = {x}
    <ul>
    	<li>例如,表达式 <code>"a"</code> 表示字符串 <code>"a"</code>。</li>
    	<li>而表达式 <code>"w"</code> 就表示字符串 <code>"w"</code>。</li>
    </ul>
    </li>
    <li>当两个或多个表达式并列,以逗号分隔,我们取这些表达式中元素的并集。<code>R({e_1,e_2,...}) = R(e_1)&nbsp;∪ R(e_2)&nbsp;∪ ...</code>
    <ul>
    	<li>例如,表达式 <code>"{a,b,c}"</code> 表示字符串&nbsp;<code>"a","b","c"</code>。</li>
    	<li>而表达式 <code>"{{a,b},{b,c}}"</code> 也可以表示字符串&nbsp;<code>"a","b","c"</code>。</li>
    </ul>
    </li>
    <li>要是两个或多个表达式相接,中间没有隔开时,我们从这些表达式中各取一个元素依次连接形成字符串。<code>R(e_1 + e_2) = {a + b for (a, b) in&nbsp;R(e_1)&nbsp;× R(e_2)}</code>
    <ul>
    	<li>例如,表达式 <code>"{a,b}{c,d}"</code> 表示字符串&nbsp;<code>"ac","ad","bc","bd"</code>。</li>
    </ul>
    </li>
    <li>表达式之间允许嵌套,单一元素与表达式的连接也是允许的。
    <ul>
    	<li>例如,表达式 <code>"a{b,c,d}"</code> 表示字符串&nbsp;<code>"ab","ac","ad"​​​​​​</code>。</li>
    	<li>例如,表达式 <code>"a{b,c}{d,e}f{g,h}"</code> 可以表示字符串&nbsp;<code>"abdfg", "abdfh", "abefg", "abefh", "acdfg", "acdfh", "acefg", "acefh"</code>。</li>
    </ul>
    </li>
    

给出表示基于给定语法规则的表达式 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 用以表示一组基于题目描述中语法构造的字符串

解法

方法一:递归

设计递归函数 dfs(exp)

  • 如果 exp 不包含 {},将 exp 中的字符加入结果集 s 中,返回;
  • 否则,找到第一个 } 的位置 $j$,从 $j$ 往前找到第一个 { 的位置 $i$,将 $exp[i+1..j-1]$ 之间的字符串按照 , 分割,得到一个字符串数组 bs。将 exp[0..i-1]exp[j+1..] 作为前缀 $a$ 和后缀 $c$,分别与 bs 中的每个字符串 $b$ 拼接,然后递归调用 dfs(a+b+c)

最后对结果集排序,返回。

Python3

class Solution:
    def braceExpansionII(self, expression: str) -> List[str]:
        def dfs(exp):
            j = exp.find('}')
            if j == -1:
                s.add(exp)
                return
            i = j
            while exp[i] != '{':
                i -= 1
            a, c, = exp[:i], exp[j + 1:]
            for b in exp[i + 1: j].split(','):
                dfs(a + b + c)

        s = set()
        dfs(expression)
        return sorted(s)

Java

class Solution {
    private TreeSet<String> s = new TreeSet<>();

    public List<String> braceExpansionII(String expression) {
        dfs(expression);
        return new ArrayList<>(s);
    }

    private void dfs(String exp) {
        int j = exp.indexOf('}');
        if (j == -1) {
            s.add(exp);
            return;
        }
        int i = j;
        while (exp.charAt(i) != '{') {
            --i;
        }
        String a = exp.substring(0, i);
        String c  = exp.substring(j + 1);
        for (String b : exp.substring(i + 1, j).split(",")) {
            dfs(a + b + c);
        }
    }
}

C++

class Solution {
public:
    set<string> s;
    vector<string> braceExpansionII(string expression) {
        dfs(expression);
        return vector<string>(s.begin(), s.end());
    }

    void dfs(string exp) {
        int j = exp.find('}');
        if (j == -1) {
            s.insert(exp);
            return;
        }
        int i = j;
        while (exp[i] != '{') {
            --i;
        }
        string a = exp.substr(0, i);
        string c = exp.substr(j + 1);
        stringstream ss(exp.substr(i + 1, j - i - 1));
        string b;
        while (getline(ss, b, ',')) {
            dfs(a + b + c);
        }
    }
};

Go

func braceExpansionII(expression string) []string {
	s := map[string]struct{}{}
	var dfs func(exp string)
	dfs = func(exp string) {
		j := strings.IndexByte(exp, '}')
		if j == -1 {
			s[exp] = struct{}{}
			return
		}
		i := j
		for exp[i] != '{' {
			i--
		}
		a, c := exp[:i], exp[j+1:]
		for _, b := range strings.Split(exp[i+1:j], ",") {
			dfs(a + b + c)
		}
	}
	dfs(expression)
	ans := []string{}
	for v := range s {
		ans = append(ans, v)
	}
	sort.Strings(ans)
	return ans
}

...