您的位置:首页 > 其它

字符串应用之全排列

2017-02-06 14:53 218 查看
之前在leetcode做过全排列的题目,LeetCode46和LeetCode47分别是不带重复元素和带重复元素的全排列,当时图个简单,直接用STL的next_permutation去做了,这一次把递归算法学习了一遍。

不重复元素的全排列

对于1234….n这样的全排列,他的全排列有n!种,因此求解该问题的时间复杂度为n!。其实要求全排列,无非就是对元素进行交换,使他们出现在不同的位置。

代码

class Solution {
private:
void func(vector<vector<int>>&res,vector<int>&nums,int n)
{
if(n==nums.size()-1)
{
res.push_back(nums);
return;
}
for(int i=n;i<nums.size();++i)
{
swap(nums[i],nums
);
func(res,nums,n+1);
swap(nums[i],nums
);
}
}
public:
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>>res;
func(res,nums,0);
return res;

}
};


重复元素的全排列

由于我们是迭代的交换元素,当迭代到某个元素时,如果前面出现过一样的元素,那么就无需再做这次交换了。

代码

class Solution {

#if 1
bool dup(vector<int>&nums,int n,int t)
{
for(int j=n;j<t;++j)
{
if(nums[j]==nums[t])
return true;
}
return false;
}
#endif
void func(vector<vector<int>>&res,vector<int>&nums,int n)
{
if(n==nums.size()-1)
{
res.push_back(nums);
return;
}

for(int i=n;i<nums.size();++i)
{

if(dup(nums,n,i))
{
continue;
}

swap(nums[i],nums
);
func(res,nums,n+1);
swap(nums[i],nums
);
}
}
public:
vector<vector<int>> permuteUnique(vector<int>& nums) {
vector<vector<int>>res;
func(res,nums,0);
return res;
}
};


降低时间复杂度

由于迭代的判断是否重复会增加时间复杂度,我们可以用一个set保存出现过的元素,空间换时间。

class Solution {

#if 0
bool dup(vector<int>&nums,int n,int t)
{
for(int j=n;j<t;++j)
{
if(nums[j]==nums[t])
return true;
}
return false;
}
#endif
void func(vector<vector<int>>&res,vector<int>&nums,int n)
{
if(n==nums.size()-1)
{
res.push_back(nums);
return;
}
// visit.clear();
//  unordered_map<int,int>dup;
unordered_set<int>dup;
for(int i=n;i<nums.size();++i)
{
if(dup.find(nums[i])!=dup.end())
continue;
dup.insert(nums[i]);
/*
if(dup(nums,n,i))
{
continue;
}
*/
swap(nums[i],nums
);
func(res,nums,n+1);
swap(nums[i],nums
);
}
}
public:
vector<vector<int>> permuteUnique(vector<int>& nums) {
vector<vector<int>>res;
func(res,nums,0);
return res;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: