首页 > 代码库 > [Leetcode]Permutations && Permutations II
[Leetcode]Permutations && Permutations II
Given a collection of 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]
, and [3,2,1]
.
组合的题目,第一题无重复,第二题有重复。
自我感觉最常规的方法就是回溯法,两道题都试用。第一道没有重复的情况下还可以有更取巧的办法,第二题貌似只能用回溯法。
先看第一题。
用回溯法,假设一共n个数字,对结果中的每一位元素i,都要把所有数字带进去试一下,只要不和前面的数字重复就OK。
class Solution { public: vector<vector<int> > result; vector<vector<int> > permute(vector<int> &num) { int n = num.size(); vector<int> oneAnswer; searchAnswer(oneAnswer,num,n,0); return result; } void searchAnswer(vector<int> &oneAnswer,vector<int> num,int n,int index){ for (int i = 0; i < n;i++){ if (!repeat(oneAnswer,num[i])){ oneAnswer.push_back(num[i]); if (oneAnswer.size() == n){ result.push_back(oneAnswer); oneAnswer.pop_back(); return; } searchAnswer(oneAnswer,num,n,index+1); oneAnswer.pop_back(); } } } bool repeat(vector<int> oneAnswer,int x){ for (int i = 0; i < oneAnswer.size(); i++){ if (x == oneAnswer[i]){ return true; } } return false; } };还有一种方法就是类似建立一个树。
最后排列的结果,第一个元素可能有四种情况,那就将1、2、3、4个元素分别和第一个元素交换位置,每个元素交换位置之后为了方便下一个元素交换,要先把位置换回去,也就是回到数组的初始状态。然后是第二个元素和后面的元素交换。
class Solution{ public: vector<vector<int> > permute(vector<int> &num){ vector<vector<int> > result; dfs(result,num,0); return result; } void dfs(vector<vector<int> > &result,vector<int> &num,int cur){ if(cur == num.size()){ result.push_back(num); } else{ for(int i = cur;i < num.size();i++){ swap(num[i],num[cur]); dfs(result,num,cur+1); swap(num[i],num[cur]); } } } };
然后是第二题。
[1,1,2]
have the following unique permutations:[1,1,2]
, [1,2,1]
, and [2,1,1]
.
第二题数组中有重复元素,那就不能像第一题那样使用回溯条件了。
1、在每一步迭代(或者说结果的每一个位置上)中,出现过的元素就不能再出现了。比如说上边的例子,第一个位置是元素第一个1,那么第二个1就不能出现在这个位置上。因此,我们给每一位设置一个出现过的元素数组vector<int> used,来保存已经出现的元素,这些元素是不能再一次出现在这个位置上的。
2、在上面条件满足的基础上,不同位置上是可以出现重复元素的,因此不能像第一题中那样再去检查元素是否重复了。元素可以重复,但是他们的下标是不能重复的。因此我们在用一个vector<int> indexUsed,来保存出现过的元素下标就可以了。
class Solution { public: vector<vector<int> > result; vector<vector<int> > permuteUnique(vector<int> &num) { int n = num.size(); vector<int> oneAnswer; vector<int> indexUsed; searchAnswer(oneAnswer, num, indexUsed, n, 0); return result; } void searchAnswer(vector<int> &oneAnswer, vector<int> num,vector<int> indexUsed, int n, int index){ vector<int> used; for (int i = 0; i < n; i++){ if (!repeat(used, num[i])&&!repeat(indexUsed,i)){ used.push_back(num[i]); oneAnswer.push_back(num[i]); indexUsed.push_back(i); if (oneAnswer.size() == n){ result.push_back(oneAnswer); oneAnswer.pop_back(); indexUsed.pop_back(); return; } searchAnswer(oneAnswer, num, indexUsed, n, index + 1); oneAnswer.pop_back(); indexUsed.pop_back(); } } } bool repeat(vector<int> oneAnswer, int x){ for (int i = 0; i < oneAnswer.size(); i++){ if (x == oneAnswer[i]){ return true; } } return false; } };
[Leetcode]Permutations && Permutations II