剑指offer:面试题28——字符串的排列
题目:输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
输入描述:
输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
思路:每次可以分为两步:
第一步是将第一个字符和后面每个字符依次交换
第二步是固定第一个字符,递归求后面字符的排列
为了去重,如果当前位字符和当前串第一位相同,不用交换直接进行下次递归
为了防止序列被递归交换后导致顺序改变从而影响后面的递归,发生某个序列被重复排列的情况,要使用两次交换,每次交换——递归——数值恢复原样——进行下次递归
class Solution {
public:
void Permutation(string str,int begin,vector<string>&strArray)
{
//当串遍历到最后一位时调出并开始返回遍历
if(begin==str.size()-1)
{
strArray.push_back(str);
}
else
{
for(int i=begin;i<str.size();i++)
{
//这里是当存在重复的字母时候,用于字符去重。即
//aab与aab中的两个a交换无意义,所以如果遍历到哪个
//字符与a相同则不用交换,直接调出
if(i!=begin &&str[i]==str[begin])
continue;
//开始交换
swap(str[i],str[begin]);
Permutation(str,begin+1,strArray);
//为了防止发生重复,比如abc递归后变为acb,但防止后面
//acb串的交换结果和当前结果重复,所以递归一次结束后,
//要将开始位置的串再换回去
swap(str[i],str[begin]);
}
}
}
public:
vector<string> Permutation(string str) {
vector <string>strArray;
if(str.empty()) return strArray;
Permutation(str,0,strArray);
//这里是保证能够按照字典序输出
sort(strArray.begin(),strArray.end());
return strArray;
}
};