剑指 Offer 38. 字符串的排列
难度中等357
输入一个字符串,打印出该字符串中字符的所有排列。
你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。
示例:
1 | 输入:s = "abc" |
限制:
1 | 1 <= s 的长度 <= 8 |
回溯
1 | class Solution { |
回溯去重
1 | class Solution { |
高效的写法
我们求整个字符串的排列,可以看成两步:
首先求所有可能出现在第一个位置的字符,即把第一个字符和后面所有的字符交换。
固定第一个字符,求后面所有字符的排列。这个时候我们仍把后面的所有字符分成两部分:后面字符的第一个字符,以及这个字符之后的所有字符。然后把第一个字符逐一和它后面的字符交换
(套娃)
1 | class Solution { |
如果输入n个字符,则这n个字符能构成长度为1的组合、长度为2的组合、……、长度为n的组合。
在求n个字符的长度为m(1≤m≤n)的组合的时候,我们把这 n 个字符分成两部分:
第一个字符和其余的所有字符。
如果组合里包含第一个字符,则下一步在剩余的字符里选取m-1个字符;
如果组合里不包含第一个字符,则下一步在剩余的 n-1 个字符里选取m个字符。
也就是说,我们可以把求n个字符组成长度为m的组合的问题分解成两个子问题,分别求n-1个字符串中长度为m-1的组合,以及求n-1个字符的长度为m的组合。这两个子问题都可以用递归的方式解决。
参考文献