class Solution {
public:
/***********字典序法解决全排列 给研究排序的人员致敬 致以我的respect********/
/*算法链接: https://blog.csdn.net/qq_34672688/article/details/79557380?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link*/
/*算法1:
* (1)从右向左找出第一个正序(即当前元素小于后一个元素),假设找到的元素为
*list[start] == a.
* (2) 重新从右向左找出第一个大于a的元素,并假设当前元素为 list[end] == b
* (3) 交换list[start]和list[end]
* (4) 将start后面的序列从小到大排列
* (5)此时的序列为一次新排列,将它储存,并进行下一次排列
*方法2:
* 直接使用库函数:
* bool next_permutation(last,end) 实现方法可能与上述相同
* 功能:计算下一个字典序列
* bool prev_permutarion(last,end)
* 功能:计算上一个字典序列
*/
vector<string> Permutation(string str) {
return myPermutation(str);
}
vector<string> myPermutation(string str){
/*先将当前序例推进去,算作一次排列*/
int start = 0;int end = 0;
vector<string> result;
result.push_back(str);
sort(str.begin(), str.end());
while(1){
/*(1)找出list[start],返回start*/
start = findStart(str);
if(start == -1){
break;
}
/* (2)找出list[end],返回end*/
end = findEnd(str,str[start]);
if(end == -1){
break;
}
/* (3)交换list[start],list[end]*/
swap(str[start],str[end]);
/* (4)对start+1-末尾进行排序*/
/* 4.1 快排 */
qucikSort(str,start+1, str.size()-1);
/* 4.2 sort排序 */
/*string::iterator it = str.begin()+start+1;
if(it != str.end()){
sort(it,str.end());
}*/
/* (5)储存结果,进行下一次排序*/
result.push_back(str);
}
return result;
}
int findStart(string s){
for(int i = s.size()-1;i>=1;i--){
if(s[i-1] < s[i]){
return i-1;
}
}return -1;
}int findEnd(string s,char ch){
for(int i = s.size()-1;i>=1;i--){
if(s[i] > ch){
return i;
}
}return -1;
}void qucikSort(string& s,int start,int end){
if(end > s.size()-1 || start > end){
return;
}else{
char cmp = s[end];
int pos = start-1;
for(int i =start;i<=end;i++){
if(s[i] < cmp){
swap(s[i],s[++pos]);
}
}swap(s[++pos],s[end]);
qucikSort(s,start,pos-1);
qucikSort(s,pos+1, end);
}
}
};