题目描述
输入一个字符串,打印出该字符串中字符的所有排列。
你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。
示例:
输入:s = "abc"
输出:["abc","acb","bac","bca","cab","cba"]
说明: 1 <= s 的长度 <= 8
题目链接: https://leetcode-cn.com/problems/zi-fu-chuan-de-pai-lie-lcof/
思路
使用回溯来做。一般使用回溯来做每一层搜索的起点 start 都是根据上一层得到的。在求全排列问题时,每一次都是从头开始,也就是从下标 0 开始搜索。同时使用 visit 数组标记在本轮搜索中位置 i 是否已经被添加到答案当中去了。
代码如下:
class Solution {
public:
vector<string> permutation(string s) {
if(s.empty()) return {};
vector<string> ans;
unordered_set<string> lookup; // 用来去重
int start = 0; // 搜索开始的位置
string cur = "";
vector<bool> visit(s.size(), false);
dfs(s, start, cur, visit, lookup, ans);
return ans;
}
void dfs(string& s, int start, string cur, vector<bool>& visit, unordered_set<string>& lookup, vector<string>& ans){
if(cur.size()==s.size()){
if(lookup.count(cur)==0){
ans.push_back(cur);
lookup.insert(cur);
}
return;
}
for(int i=0; i<s.size(); i++){
if(!visit[i]){
cur += s[i];
visit[i] = true;
dfs(s, i+1, cur, visit, lookup, ans);
visit[i] = false;
cur.pop_back();
}
}
}
};
上面的代码中,变量 start 不是必须的,因为没有用到这个变量,写在里面是为了和其他回溯的写法统一起来。