您的位置:首页 > 其它

算法Week08.04 - LeetCode 46. Permutations

2016-10-19 21:15 288 查看


题意大意

给定一组互不相同的数字,返回所有可能的排列。


难度

Medium


个人题解


方法一

stl算法库已经提供了排列相关的算法
next_permutation

以及
prev_permutation
,所以首先想到的方法是使用
next_permutation

试试规模如何。

next_permutation

从当前排列产生下一个排列需要如下4步:

从后往前,找到第一个连续的顺序对(a,b);

从后往前,找到第一个比a大的数c;

交换a和c;

反转介于a和c之间的数。

时间复杂度为O(n)。

全排列一共有n!种,产生每种排列的复杂度为O(n),因而总时间复杂度为O(n*n!)。需要特别注意的是,
next_permutation

是按顺序进行的,所以只有初始状态最小才可能产生所有的排列;因而需要先对序列进行排序或者综合使用
next_permutation

以及
prev_permutation



方法二

使用深度优先搜索,开一个与序列元素一一对应的布尔数组
unsel[]

,如果序列中某一个元素已经被选择过了,那么对应的布尔值为
false

,否则为
true


那么对于一个长度为
n

的序列,其搜索树每一层的节点数分别为:1、n、n*(n-1)、n*(n-1)*(n-2)、...、n!、n!,边数分别为:n、n*(n-1)、n*(n-1)*(n-2)、...、n!、n!,每一个叶子节点导出一种排列。在布尔数组的基础上建立链表,将所有值为
true

的节点连接起来,那么从一个节点转移到下一个节点的复杂度为O(1),因而时间复杂度为(1+2*(n+n*(n-1)+...+n!+n!))*O(1)=(1+2e*n!)*O(1)=O(n!)。


源代码


方法一

#include<algorithm>
classSolution{
public:
 vector<vector<int>>permute(vector<int>&nums){
   std::sort(nums.begin(),nums.end());
   vector<vector<int>>out;
   out.push_back(nums);
   while(std::next_permutation(nums.begin(),nums.end())){
     out.push_back(nums);
   }
   returnout;
 }
};


方法二

classSolution{
public:
 structMyBool{
   boolval;
   shortidx;
   MyBool*next;
 };
 
 vector<vector<int>>permute(vector<int>&nums){
   vector<vector<int>>out;
   if(!nums.size()){
     out.push_back(nums);
     returnout;
   }
   
   vector<int>ele;
   MyBool*un_sel=newMyBool[nums.size()];
   for(inti=0;i<nums.size();i++){
     un_sel[i].val=true;
     un_sel[i].idx=i;
     un_sel[i].next=un_sel+i+1;
   }
   un_sel[nums.size()-1].next=NULL;
   MyBool*head=un_sel;
   dfs(nums,ele,out,un_sel,head);
   returnout;
 }
 staticvoiddfs(constvector<int>&nums,vector<int>&ele,vector<vector<int>>&out,MyBool*un_sel,MyBool*head){
   if(!head)out.push_back(ele);
   else{
     MyBool*cur=head;
     MyBool*prev=NULL;
     cur->val=false;
     ele.push_back(nums[cur->idx]);
     dfs(nums,ele,out,un_sel,cur->next);
     ele.pop_back();
     cur->val=true;
     prev=cur;
     cur=cur->next;
     
     while(cur){
       prev->next=cur->next;
       cur->val=false;
       
       ele.push_back(nums[cur->idx]);
       dfs(nums,ele,out,un_sel,head);
       ele.pop_back();
       cur->val=true;
       prev->next=cur;
       prev=cur;
       cur=cur->next;
     }
   }
 }
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息