通过率 57% · 提交 1,003 · 通过 575
小慕手头有 `M (0<M<=30)` 个字符,全部来自小写字母 `a-z`。他打算从中挑选一些字符(),拼成一个长度为 `N (0<N<=5)` 的字符串。规则是:拼出来的字符串中,。现在小慕想知道,给定这些字符,一共能拼出多少种满足条件的字符串。如果,或者无论如何都无法拼出符合条件的字符串,则返回 `0`。
这类题属于华为 OD 机考真题方向中「200分 / DFS」方向的高频题型,通常考察对「200分 / DFS」的建模能力与边界条件处理。掌握本题的解题思路后,可举一反三应对同类真题方向,稳步提升机考通过率。
提示:带虚线的词点一下有通俗解释。
给定的字符列表和结果字符串长度,中间使用空格(" ")拼接
满足条件的字符串个数
示例 1
输入示例
aabc 3
输出示例
8
给定的字符为aabc,结果字符串长度为3,可以拼接成abc,acb,bac,bca,cba,cab,aba,aca,共8种
示例 2
输入示例
abc 1
本平台为独立第三方培训机构,与华为技术有限公司无任何关联;课程的服务内容与权益以购买协议为准,学习效果因个人情况而异。「华为 OD」「华为可信」等仅为对岗位与考试方向的客观描述,相关商标归各自权利人所有。
本题数据量不大,虽然只是要求枚举数量而不是枚举具体的字符串,但仍然可以通过回溯来解决。
注意到在本题中,原输入字符串 s 中的字符顺序并不重要,只有出现次数是关键信息。 所以很容易考虑应该使用哈希表计数器来统计 s 中各个字符出现的次数。即:
特别注意,由于本题存在重复字符,而重复字符可能会导致重复的排列。 因此相比起 经典题型、全排列,本题在问题的定义上更加接近 经典题型、全排列 II。
回溯的重点在于回溯函数的编写。函数传参需要包含三个参数:
n:目标字符串的长度path:当前所选择的路径字符串的情况cnt:原字符串 s 中的字符剩余情况显然当 len(path) == n 时,我们找到了一个长度为 n 的拼接字符串,更新 ans 并退出递归,即:
我们需要考虑 cnt 中的所有 key 以及这些 key 的 value。当:
value == 0 时,说明 key 这个字符已经在之前被选择完了,无法再选path and key == path[-1] 时,说明此时 key 和当前 path 的最后一个字符一致,此时是不能够选择 key 延长在 path 的后面的对于上述两种情况,都可以直接跳过该 (key, value) 对。
当不满足上述情况时,则可以进行状态更新和回溯,以及回溯结束后的回滚操作。即:
综上,整体的回溯函数为:
这就完成了本题的核心递归函数。
至于递归入口,则传入 path = "" 即可。 另外题目说明当出现非法输入时需要返回 0,因此还需要判断 s 中的每一个字符是否均为小写字符。 故主函数部分为:
当然,本题也可以不借助哈希表,直接使用类似课上讲过的 经典题型、全排列 II 的去重方法,来避免出现重复统计的问题。即:
PS:感兴趣的同学可以思考一下如何使用 dp 完成这个问题。
复杂度分析
登录后可查看你在本题的历史提交,以及每次的各用例通过情况。
输出示例
3
给定的字符为abc,结果字符串长度为1,可以拼接成a,b,c,共3种
时间限制 1000 ms · 内存限制 128 MB
© 2026 广州慕课网络科技有限公司 · 吴师兄学算法官网 版权所有