题目描述
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
全排序思路:
这个问题主要是思路不好想。可以采用递归的思想:
1、先固定左边的一个元素,然后对剩余元素进行全排列,如abcd,则先固定a,再递归对bcd进行全排列;
2、一次将第一个元素和后面的元素进行交换,然后再进行步骤1;
重复问题:
如果存在重复的元素,如b a c a d,b和第1个a交换之后,排列为:
a (b c a d)
和第2个a交换之后,排列为:
a (a c b d)
两个排列,对括号中的元素再次进行全排列,必然会都是重复的,因此和第2各a交换之后的排列应该剪掉,剪掉的条件就是:
第k个元素和第i个元素交换,那么[k,i)中存在和第i个元素相同的元素
//判断第i个元素在前面是否出现过
bool bRepeatBefore(string &str, int k, int i)
{
for(int j=i-1; j>=k; j--)
{
if(str[i] == str[j])
{
return true;
}
}
return false;
}
void swap(string &str, int i, int j)
{
char temp = str[i];
str[i] = str[j];
str[j] = temp;
}
vector<string> v;
void PermutationCore(string &str, int k, int m)
{
if(k == m)
{
v.push_back(str);
}
else
{
for(int i=k; i<=m; i++)
{
if(bRepeatBefore(str, k, i) == false)
{
swap( str, k, i);
PermutationCore(str, k+1, m);
swap(str, k, i);
}
}
}
}
vector<string> Permutation(string str) {
int len = str.size();
if(len <= 0)
{
return v;
}
PermutationCore( str, 0, len-1);
return v;
}