保持字符顺序删除字符生成字符串的术语及实现算法咨询
对应正确术语
你需要的概念的标准术语是子序列(Subsequence),你需求中的输出恰好是原字符串的所有非空子序列。
子序列的核心定义为:在不改变原序列元素相对顺序的前提下,删除任意个(可以是0个)元素后得到的新序列。
常见易混淆概念区分:
- 排列(Permutation):不要求保持原元素相对顺序,且必须使用所有元素重新排列得到结果,和你的需求差异较大
- 子串(Substring):要求元素是原序列中连续的片段,同样保持顺序,但不会出现你示例中"AC"这类跳过中间字符的结果
- 幂集(Power Set):字符串的所有子序列集合和它的字符位置幂集是一一对应的,每个位置的「选/不选」状态对应最终子序列是否包含该位置的字符
可参考的相关算法
- 回溯法
最直观的实现方案,遍历字符串的每一个位置,每一步做出「保留当前字符」或「跳过当前字符」的决策,当遍历到字符串末尾时,即可得到一个合法的子序列,收集所有非空结果即可。如果原字符串存在重复字符,可以在回溯过程中增加剪枝逻辑避免生成重复子序列。
参考实现伪代码:
def get_subsequences(s): res = [] def backtrack(pos, path): if pos == len(s): if path: res.append(''.join(path)) return # 选择当前字符 path.append(s[pos]) backtrack(pos + 1, path) path.pop() # 跳过当前字符 backtrack(pos + 1, path) backtrack(0, []) return res
位枚举法
适合长度不超过20的短字符串,用二进制数的每一位代表对应位置的字符是否被选中,从1到2^n -1(n为字符串长度,排除全0对应的空序列)遍历所有整数,逐位判断即可生成所有子序列。迭代构造法
从空集合开始逐个处理原字符串的字符,每次将当前字符拼接到已经生成的所有子序列末尾,和原有子序列集合合并得到新的集合。比如处理字符串"ABC"时,步骤如下:
- 初始结果:[]
- 处理字符"A":拼接得到["A"],合并后结果为["A"]
- 处理字符"B":拼接得到["AB", "B"],合并后结果为["A", "AB", "B"]
- 处理字符"C":拼接得到["AC", "ABC", "BC"],合并后结果为["A", "AB", "B", "AC", "ABC", "BC", "C"]
该方法实现简单,也可以很方便的增加去重逻辑处理含重复字符的场景。
内容的提问来源于stack exchange,提问作者user1621001
相关产品推荐
相关产品推荐

