输入一个字符串,打印出该字符串中字符的所有排列。
你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。
示例:
输入:s = "abc"
输出:["abc","acb","bac","bca","cab","cba"]
限制:
1 <= s 的长度 <= 8
解题思路:
**和这个相似:**https://blog.csdn.net/qq_30457077/article/details/114375222
重复排列方案与剪枝:
当字符串存在重复字符时,排列方案中也存在重复的排列方案。为排除重复方案,需在固定某位字符时,保证 “每种字符只在此位固定一次” ,即遇到重复字符时不交换,直接跳过。从 DFS 角度看,此操作称为 “剪枝” 。
class Solution {
public:
vector<string> permutation(string s) {
dfs(s, 0);
return res;
}
private:
vector<string> res;
void dfs(string s, int x) {
if(x == s.size() - 1) {
res.push_back(s); // 添加排列方案
return;
}
set<int> st;//首先vector属于顺序容器,其元素与存储位置与操作操作有关;
//set属于关联容器,其元素相当于键值。set能够保证它里面所有的元素都是不重复的(multiset除外)。
//因此,此处用set
for(int i = x; i < s.size(); i++) {
if(st.find(s[i]) != st.end()) continue; // 若s[i]存在于st,重复,因此剪枝
st.insert(s[i]);//将 c[i] 加入 Set ,以便之后遇到重复字符时剪枝;
swap(s[i], s[x]); // 交换,将 s[i] 固定在第 x 位;因为此处已经交换
//,所以x == s.size() - 1时,执行res加入新元素
/* if(x == s.size() - 1) {
res.push_back(s); // 添加排列方案
return;
}
*/
dfs(s, x + 1); // 开启固定第 x + 1 位字符
swap(s[i], s[x]); // 恢复交换
}
}
};
复杂度分析:
作者:jyd
链接:https://leetcode-cn.com/problems/zi-fu-chuan-de-pai-lie-lcof/solution/mian-shi-ti-38-zi-fu-chuan-de-pai-lie-hui-su-fa-by/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。