剑指offer题目:
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
即leetcode 46&47
46. Permutations(47.PermutationsII就是要考虑重复元素)
Given a collection of distinct numbers, return all possible permutations.
For example,
[1,2,3] have the following permutations:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
假设字符串内无重复元素时,下述代码正确。
vector<string> res;
void help(string s, int n){
if (n == 0){
res.push_back(s);
}
for (int i = 0; i <= n; i++){
swap(s[i], s[n]);
help(s, n - 1);
swap(s[i], s[n]);
}
}
vector<string> Permutation(string str) {
if (str.size() == 0)
return res;
help(str, str.size() - 1);
//sort(str.begin(), str.end());
return res;
}
上述代码通在有重复元素时不准确,会包含重复的序列结果。去掉也很简单,还有加上判断语句,去掉有重复元素的递归操作
s[i]==s[n] 去掉前面重复的元素,如aab
s[i]==s[i-1] 去掉后面重复的元素,如abb
if(i!=n&&(s[i]==s[n]||s[i]==s[i-1]))
continue;
for (int i = 0; i <= n; i++){
swap(s[i], s[n]);
help(s, n - 1);
swap(s[i], s[n]);
}
完整代码
class Solution {
public:
vector<string> res;
vector<string> Permutation(string str) {
if(str.size()==0)
return res;
help(str,0);
sort(res.begin(),res.end());
return res;
}
void help(string s,int n){
if(n==s.size()-1){
res.push_back(s);
}
for(int i=n;i<s.size();i++){
if(i!=n&&(s[i]==s[n]||s[i]==s[i-1]))
continue;
swap(s[i],s[n]);
help(s,n+1);
swap(s[i],s[n]);
}
}
};
2017-08-31修改
上面的代码还是有问题,牛客网上测试通过,但leetcode的permutationII是AC不过去的(如序列[-1,2,0,-1,1,0,1]),还没找到问题,只好参考九章上给的AC代码了
class Solution {
private:
void helper(vector<vector<int> > &results,
vector<int> &permutation,
vector<int> &nums,
bool used[]) {
if (nums.size() == permutation.size()) {
results.push_back(permutation);
return;
}
for (int i = 0; i < nums.size(); i++) {
if (used[i]) {
continue;
}
if (i > 0 && used[i - 1] == false && nums[i] == nums[i-1]) {
continue;
}
used[i] = true;
permutation.push_back(nums[i]);
helper(results, permutation, nums, used);
permutation.pop_back();
used[i] = false;
}
}
public:
vector<vector<int> > permuteUnique(vector<int> &nums) {
vector<vector<int> > results;
vector<int> permutation;
bool used[nums.size()];
for (int i = 0; i < nums.size(); i++) {
used[i] = false;
}
sort(nums.begin(), nums.end());
helper(results, permutation, nums, used);
return results;
}
};
本文介绍了一种用于生成字符串所有可能排列的算法,并针对有无重复元素的情况进行了区分处理。提供了详细的代码实现,包括如何避免重复排列的问题。
1492

被折叠的 条评论
为什么被折叠?



