剑指 Offer 38. 字符串的排列
题目描述:
输入一个字符串(字符可能有重复),打印出该字符串中字符的所有排列。
你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。
示例:
输入:s = "abc"
输出:["abc","acb","bac","bca","cab","cba"]
解题思路:
经典的dfs全排列+一点小套路
1. 为了避免重复,先sort一下,让重复的数字挨着
2. 剪枝: 除了被访问过不能再用之外,假如 i>0 && nums【i】==nums【i-1】 && !visited【i-1】 也不能用。也就是假如一长串相等的,只有排在前面的先被用了,后面的才能被用。
代码:
//
class Solution {
public:
vector<string> permutation(string s) {
if (s.empty())
return {};
// 为了避免重复,先sort一下,让重复的数字挨着
sort(s.begin(), s.end());
string one(s.size(), 0);
vector<bool> visited(s.size(), false);
vector<string> res;
dfs(res, visited, s, one, 0);
return res;
}
void dfs(vector<string>& res, vector<bool>& visited, string& s, string& one, int cur)
{
if (cur == s.size())
{
res.push_back(one);
return;
}
for (int i = 0; i != s.size(); ++i)
{
if (visited[i])
continue;
// 剪枝: 假如一长串相等的,只有排在前面的先被用了,后面的才能被用。
if (i > 0 && s[i] == s[i-1] && !visited[i-1])
continue;
visited[i] = true;
one[cur] = s[i];
dfs(res, visited, s, one, cur+1);
visited[i] = false;
}
}
};