给定一个没有重复数字的序列,返回其全部可能的全排列。函数
示例:ui
输入: [1,2,3] 输出: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ]
vector<vector<int>> permute(vector<int>& nums) spa
一、给定一个一维的vector,里面装着彼此不重复的int型整数,要求输出全部这些整数有可能组成的全排列。指针
每一个全排列存储在一维的vector中,全部的全排列存储在二维的vector中,最后返回二维的vector。code
二、这道题又是熟悉的树开枝散叶类的题目,这种题咱们都是用递归作的。blog
在树的每一个节点上,规律是一致的,用递归是最方便的作法。递归
举个例子,好比[1,2,3,4],咱们在第一个节点上,有4种选择,1/2/3/4,io
若是选择了2,那么第二个节点上,有3种选择,1/3/4,class
若是选择了4,那么第三个节点上,有2种选择,1/3。gui
但存在一个问题,咱们怎么知道当前节点上的全部选择?咱们要建一个“弹药库”吗,每次迭代一个进入循环?
但其实全排列就是元素之间的不断交换,咱们能够利用这一点,下降时间复杂度。
代码以下:(附详解)
void digui(vector<int>& nums,vector<vector<int>>& res,int left,int right,int* t) { if(left==right)//退出条件 { res[*t]=nums; (*t)++; return; } for(int i=left;i<=right;i++)//当i==left时,其实没有交换,直接进入递归,当i!=left时,发生交换,进入递归 { swap(nums[i],nums[left]); digui(nums,res,left+1,right,t); swap(nums[i],nums[left]); } } vector<vector<int>> permute(vector<int>& nums) { int s1=nums.size(),result=s1,left=0,right=s1-1,count=0;//count表示当前是第几个全排列 int *t=&count;//定义一个指针,指向count,便于后续处理 for(int i=s1-1;i>1;i--)//result表示一共有多少个全排列 result*=i; vector<vector<int>>res(result,nums);//提早申请好空间,避免屡次申请空间形成的时间浪费 digui(nums,res,left,right,t);//直接进入递归 return res;//最终返回二维的vector }
还不是很清楚的同窗,能够手推一下全过程,逻辑会清晰不少。
这道题咱们不用自建“弹药库”,交换一下nums中的元素,nums就是咱们的弹药库。
上述代码实测8ms,beats 100.00% of cpp submissions。