「这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战」
描述
无重复字符串的排列组合。编写一种方法,计算某字符串的所有排列组合,字符串每个字符均不相同。
- 示例 1:
输入:S = "qwe"
输出:["qwe", "qew", "wqe", "weq", "ewq", "eqw"]
输入:S = "qwe"
输出:["qwe", "qew", "wqe", "weq", "ewq", "eqw"]
- 示例 2:
输入:S = "ab"
输出:["ab", "ba"]
- 提示:
- 字符都是英文字母。
- 字符串长度在[1, 9]之间。
解析
将参数字符串分解成一个个字符,每次从字符取一个,然后然后将字符与原先组成的字符串进行组合,该字符的位置是原字符串的任意位置,组合成新的字符串。 先取a作为原始列表字符串,然后按顺序取b,生成ba,ab两个字符串的列表, 然后按顺序取c,c与ba组合放在ba任意位置,组成cba,bca,bac, c与ab组合放在ab任意位置,组成cab,acb,abc, 依次类推 生成完整的字符列表
class Solution {
public String[] permutation(String S) {
char[] chs = S.toCharArray();
List<StringBuffer> list = new ArrayList<>();
list.add(new StringBuffer(S.substring(0, 1)));
int start = 0, end = list.size();
for(int i = 1; i < chs.length; i ++){
for(int j = start; j < end; j ++){
for(int k = 0; k <= i; k ++){
StringBuffer sb = new StringBuffer(list.get(j));
sb.insert(k, chs[i]);
list.add(sb);
}
}
start = end;
end = list.size();
}
String[] ans = new String[end - start];
int idx = 0;
for(int i = start; i < end; i ++){
ans[idx ++] = list.get(i).toString();
}
return ans;
}
}
运行结果:
执行结果:通过
执行用时:14 ms, 在所有 Java 提交中击败了50.31%的用户
内存消耗:47.7 MB, 在所有 Java 提交中击败了5.06%的用户
此外,还有一种进阶方式
- 将待排序列中的各个字符放到第1个位置上,递归调用以全排列剩余字符序列,再还原序列;
- 递归边界条件为“剩余待排列序列为空”,此时将整个字符数组转成字符串加入到结果中。
class Solution {
int idx = 0;
String[] ans;
public String[] permutation(String S) {
int sLen = S.length(), len = 1;
for(int i = 2; i <= sLen; i ++) len *= i;
ans = new String[len];
helper(S.toCharArray(), 0, sLen);
return ans;
}
public void helper(char[] chs, int start, int end){
if(start == end){
ans[idx ++] = new String(chs);
return;
}
for(int i = start; i < end; i ++){
swap(chs, start, i);
helper(chs, start + 1, end);
swap(chs, start, i);
}
}
public void swap(char[] chs, int i, int j){
char tmp = chs[i];
chs[i] = chs[j];
chs[j] = tmp;
}
}