leetcode-Permutations-46
输入一个数组,字典序输出所有组合。
这和输入一个数组,求元素和等于target的所有组合不同,这题是求全排列,每个元素都要选到,而元素和是选择任意的元素,有些元素可能不选
选择用:dfs+回溯(思路是深搜每个元素,选择,直到树的底部,如果满足条件放入结果,返回,回溯)
排列用:递归+交换(思路是对n个元素的数组想象成n层的树,全排列,每个元素都要到第i层去,所以枚举每一层,然后让每个元素都来这一层。每一层是一个递归,在递归里面用for循环让每个元素都来一次本层)
前提都是先排序
去重:每一层如果出现同样的元素,只取第一个,其余相同的元素不取,注释1
字典序:每次交换之后都对后面层数的元素排序,注释2
这题还可以直接用next_permutation(注释部分),不过我也给出了手写算法
1 class Solution { 2 public: 3 void func(vector<vector<int> > &v,vector<int> a,int low,int high){ 4 if(low==high-1){ 5 v.push_back(a); 6 return; 7 } 8 for(int i=low;i<high;i++){ 9 if(i!=low&&a[i]==a[low]) continue; //去重 10 swap(a[i],a[low]); 11 sort(a.begin()+low+1,a.end()); //字典序 12 func(v,a,low+1,high); 13 swap(a[i],a[low]); 14 } 15 } 16 vector<vector<int> > permute(vector<int>& nums) { 17 vector<vector<int> > v; 18 // sort(nums.begin(),nums.end()); 19 // do{ 20 // v.push_back(nums); 21 // }while(next_permutation(nums.begin(),nums.end())); 22 // return v; 23 sort(nums.begin(),nums.end()); 24 func(v,nums,0,nums.size()); 25 return v; 26 } 27 };