剑指 Offer 38. 字符串的排列
输入一个字符串,打印出该字符串中字符的所有排列。
按照字典序返回这个字符串数组,但里面不能有重复元素。
示例:
输入:s = “abc”
输出:[“abc”,“acb”,“bac”,“bca”,“cab”,“cba”]
限制:
1 <= s 的长度 <= 8
思路:
字符串全排列:第一个位置n种方法,第二个位置n-1种,……
实现:
void dfs(int x)
参数:x为字符串第x个位置
功能:完成第x个位置元素的选择,递归:dfs(x+1)
终止条件:完成最后一个位置元素的选择
实现方法:元素交换,如第0个位置的选择,‘a’与’a’交换,第一个元素为a,‘a’与‘b’交换,第一个元素为b,以此类推。
辅助结构:set st; 存储交换过的字符值,交换过的则不再交换,避免字符串中的重复值反复交换得到重复排列的情况。
class Solution {
public:
vector<string> res;
vector<string> Permutation(string str) {
dfs(str,0);
sort(res.begin(),res.end());
return res;
}
//安排第x个位置的值
void dfs(string& str,int x){
if(x == str.size() - 1) //最后一个值没有再交换的值
{
res.push_back(str); //所有位置已经安排好,插入返回数组即可
return;
}
set<char> st;
for(int i = x;i < str.size();++i)
{
if(st.count(str[i])) continue; //重要,该值交换过则不再交换,不然会重复
st.insert(str[i]);
swap(str[x],str[i]);
dfs(str,x+1);
swap(str[x],str[i]);
}
}
};
tips:
swap函数可直接对字符串字符位置进行交换;
sort(begin,end,回调函数);
set容器可用于hash,键值和元素值为同一个值,set.count()快速查找元素是否存在,set.insert()插入新的值。