题目描述
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
输入描述:
输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
思路:递归法,问题转换为先固定第一个字符,求剩余字符的排列;求剩余字符排列时跟原问题一样。
(1) 遍历出所有可能出现在第一个位置的字符(即:依次将第一个字符同后面所有字符交换);
(2) 固定第一个字符,求后面字符的排列(即:在第1步的遍历过程中,插入递归进行实现)。
需要注意的几点:
(1) 先确定递归结束的条件,例如本题中可设begin == str.size() - 1;
(2) 形如 aba 或 aa 等特殊测试用例的情况,vector在进行push_back时是不考虑重复情况的,需要自行控制;
(3) 输出的排列可能不是按字典顺序排列的,可能导致无法完全通过测试用例,考虑输出前排序,或者递归之后取消复位操作。
class Solution {
public:
vector<string> Permutation(string str) {
vector<string> result;
if(str.empty()) return result;
ShowAll(str, result, 0);
sort(result.begin(), result.end());
return result;
}
void ShowAll(string str, vector<string>& result, int index){
if(index == str.size()-1){
if(find(result.begin(), result.end(), str) == result.end()){
result.push_back(str);
}
}else{
for(int i=index; i<str.size(); ++i){
Swap(str[i], str[index]);
ShowAll(str, result, index+1);
}
}
}
void Swap(char& a, char& b){
char c = a;
a = b;
b = c;
}
};
下面的是之前写的,思想是一致的,只是看起来不是很好看~
输入一字符串(要求不存在重复字符),打印出该字符串中字符中字符的所有排列。
例如:输入"abc",输出结果为abc, acb, bac, bca, cab和cba。
#include <iostream>
#include <string>
using namespace std;
void swap( char *a, char *b){
char temp;
temp = *a;
*a = *b;
*b = temp;
}
void permute( char *pStr, char *pBegin);
void permute( char *pStr){
if ( pStr == NULL)
return;
permute ( pStr, pStr);
}
void permute( char *pStr, char *pBegin){
if ( *pBegin == '\0') {
cout << pStr;
} else {
for ( char *ch = pBegin ; *ch != '\0' ; ch++)
{
swap ( *ch , *pBegin);
permute ( pStr , pBegin+1);
cout <<' ';
swap ( *ch , *pBegin); //保持初始状态
}
}
}
int main(){
cout << "请输入一列字符串:" ;
char str[10];
cin >> str;
cout << "字符全排列为:" ;
permute ( str );
cout << endl;
return 0;
}
输入一字符串(要求可以存在重复字符),打印出该字符串中字符的所有排列。
例如:输入"abb",输出结果为abb, bab, bba。
去重的全排列就是从第一个数字起每个数分别与它后面非重复出现的数字交换。
例如:“abb”,第一个字符a和第二个字符b交换,得到“bab”,此时由于第二个字符和第三个字符相同,所有第一个字符“a”不与第三个字符“b“交换。再考虑,”bab“,第二个字符和第三个字符不同,交换得”bba“,此时结束。生成全部排列
加一个判断,满足条件再进行交换
- //在[nBegin,nEnd)区间中是否有字符与下标为pEnd的字符相等
- bool IsSwap(char* pBegin, char* pEnd)
- {
- char* p;
- for (p=pBegin; p<pEnd; p++)
- {
- if (*p == *pEnd)
- return false;
- }
- return true;
- }