题目:
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
思路:
首先确定第一个字母,这种情况下的排列就是剩下字符的所有排列,可以用递归完成,然后依次交换第一个字母和剩下的字母,得到不同起始字母下的所有排列。思路听起来很简单,但是有很多需要注意的点。
首先不需要单独用变量存储每个排列,直接在str上进行交换操作,然后把字符串一次压入result,所以要注意每次交换计算完所有排列后,要再交换回来,不然会有重复。
其次用一个变量start表示当前递归过程第一个字母,所以每次递归要将start+1(即先确定start位置的字母,然后递归后面的字符串),递归的结束条件时start到达最后一个字符,即不需要再交换了。
用循环来实现首字母与剩下字母交换,因为原始字符串也是一个排列,所以交换的位置i从start开始;因为可能有重复的字符,所以当i!=start,并且i和start位置的字符相同时,要跳过这些重复字符,直接i++。
最后得到的所有排列要做一个排序,保证按字典序输出。
参考代码:
在线测试:
AC代码:
class Solution {
public:
vector<string> Permutation(string str) {
vector<string> result;
if(str.empty())
return result;
Permutation(str, 0, result);
sort(result.begin(),result.end());
return result;
}
void Permutation(string str, int start, vector<string> &result)
{
if(start==str.size()-1)
{
result.push_back(str);
return;
}
for(int i=start; i<str.size(); i++)
{
if(i!=start && str[i]==str[start])
continue;
swap(str[start],str[i]);
Permutation(str, start+1, result);
swap(str[start],str[i]);
}
}
};