- 题目:输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
- idea:使用字典,保存下每个字符的数量。由于map本身就按照key排序,不需要再对map进行排序。因此直接从第一个字母开始遍历map,生成第一个字符,然后递归生成2-n的字符串,递归时应该把当前位的字母的数量-1。
- code
#include <bits/stdc++.h>
class Solution {
public:
vector<string> results(map<char, int> dict, int len){
map<char, int> cur_dict(dict);
vector<string> ctr_res;
string res = "";
if (len == 0) return ctr_res;
for (auto iter = cur_dict.begin(); iter != cur_dict.end(); iter++){
if (iter->second > 0){
string cur_str=" ";
cur_str[0] = iter->first;
res = ""+cur_str;
if (len == 1){
ctr_res.push_back(res); //假如len==1直接返回该串即可
return ctr_res;
}
iter->second--; //递归生成长度为len-1的字符串的集合,由于已经用了当前字符,当前字符的数量应该-1
vector<string> next_str = results(cur_dict, len-1);
for (int i = 0; i < int(next_str.size()); i++){
res = res + next_str[i];
ctr_res.push_back(res);
res = ""+cur_str;
}
iter->second++; //对于下一个字符开头的字符串而言,本次迭代的字符下次依然可以用
}
}
return ctr_res;
}
vector<string> Permutation(string str) {
map<char, int> dict;
vector<string> res;
if (str.length()== 0) return res;
int len = str.length();
for (int i = 0; i < len; i++){
dict[str[i]] += 1; //建立字典
}
res = results(dict, len);
return res;
}
};