输入一个字符串,打印出该字符串中字符的所有排列。你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。
示例:
输入:s = "abc" 输出:["abc","acb","bac","bca","cab","cba"]
限制:
1 <= s 的长度 <= 8
与全排列问题一样,采用深度优先遍历的方法,并且有字母重复的情况,这种题的解决方法就是先排序再去重。
之前的博客有专门写过《全排列》和《全排列二》,正是这道题从无到有的思考过程。
vector<string> res; //最终结果
string temp; //保留符合条件的字符串
vector<string> permutation(string s) {
vector<int> used(s.size(),0); //一个标记数组
sort(s.begin(),s.end()); //字符串排序
dfs(s,used); //深搜
return res; //返回结果
}
void dfs(string& s,vector<int>& used){
if(temp.size() == s.size()){ //边界条件:当重组字符串与题中所给字符串大小相等时保留结果
res.push_back(temp); //加入结果集
return; //返回上一层
}
for(int i = 0; i < s.size(); i ++){ //每个位置都从字符串第一个字母试着填入
if(i > 0 && s[i] == s[i-1] && used[i-1] == 0) continue; //去重:确保一个位置只用到重复字母的第一个,防止字符串重复出现
if(used[i] != 0) continue; //当前字母被使用过,跳过
else{ //temp的当前位置对每个字母都有填或不填两种选择
temp += s[i]; //当前位置使用s[i]
used[i] = 1;
dfs(s,used);
temp.pop_back(); //当前位置不使用s[i]
used[i] = 0;
}
}
}
运行结果: