Question
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
输入描述:
输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
Solution
abc的全排列是:abc, acb, bac, bca, cba, cab
可以看到字符串可以分为两部分,左边固定一个字符,然后右边的字符串之间交换。
然后再将第一个字符和后面的一个字符交换,保持第一个字符不动,右边的字符串之间交换。
可以看到这个是一个递归的过程。
Code
class Solution {
public:
vector<string> Permutation(string str) {
if (str.empty())
return vector<string>();
vector<string> res;
Permutation(res, str, 0);
// 字典序
sort(res.begin(), res.end());
return res;
}
void Permutation(vector<string> &array, string str, int begin) {
if (begin == str.size() - 1)
array.push_back(str);
for (int i = begin; i < str.size(); i++) {
// 和第一个字母相同的字符就不用再交换了
if (i != begin && str[i] == str[begin])
continue;
swap(str[begin], str[i]); // 交换
Permutation(array, str, begin + 1); // 递归
swap(str[begin], str[i]); // 再次交换回来
/*
需要两次交换的原因,举个例子
abca, 第一个a和自己交换,遍历后面字符串
abca, a和b交换,遍历,如果只交换一次的话,就是下面结果
baca, 那么再次交换的时候就是b和c交换,不在是a和c交换了
最后第一个a和最后一个a不用交换
*/
}
}
};