题目描述
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。字符串长度不超过9(可能有字符重复),字符只包括大小写字母。
解题思路
很典型的 DFS+回溯 问题。可以用 map 记录各个字符出现的次数,每次递归从 map 中取出一个未被用尽的字符构建新字符串。注意回溯时要恢复 map 中字符的个数和字符串状态。牛客官方解法提供了另外一种思路,它不断调换给定字符串的字符顺序,采用 swap 函数先固定第一个字符,然后递归调用固定第二个字符,最后将变换顺序后的字符串保存在 set 容器中,以达到去重的目的。
实现
class Solution {
public:
void DFS(vector<string>& strs, map<char,int>& nums, string& s)
{
bool empty=true;
map<char,int>::iterator it;
for(it=nums.begin(); it!=nums.end(); ++it)
{
if((*it).second!=0)
{
empty = false;
s.push_back((*it).first);
--(*it).second;
DFS(strs, nums, s);
++(*it).second;
s.pop_back();
}
}
if(empty) strs.push_back(s);
}
vector<string> Permutation(string str) {
int size = str.length();
map<char,int> nums;
vector<string> strs;
if(size==0) return strs;
for(int i=0; i<size; ++i)
{
if(nums.find(str[i])==nums.end())
nums[str[i]] = 0;
else ++nums[str[i]];
}
string s;
DFS(strs, nums, s);
return strs;
}
};