(i)
【题目描述】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].
【解题思路】类似于DFS的递归. 对于包含n个元素的数组,先确定第一位置的元素,第一个位置有n中可能(每次把后面的元素和第一个元素交换),然后求子数组[2…n]的全排列。由于一个数列的总共有n!个排列,因此时间复杂度为O(n!)
【考查内容】递归,数组
class Solution {
public:
vector<vector<int> > permute(vector<int> &num) {
vector<vector<int> > res;
if(num.size() == 0)
return res;
vector<int> tmpres;
permuteRecur(num, 0, res, tmpres);
return res;
}
void permuteRecur(vector<int> &num, int index, vector<vector<int> >&res, vector<int>&tmpres){
if(index == num.size()){
res.push_back(tmpres);
return;
}
for(int i = index; i < num.size(); i++){
swap(num[index], num[i]);
tmpres.push_back(num[index]);
permuteRecur(num, index+1, res, tmpres);
tmpres.pop_back();
swap(num[index], num[i]);
}
}
};
(ii)
【题目描述】Given a collection of numbers that might contain duplicates, return all possible unique permutations.
For example,
[1,1,2]have the following unique permutations:
[1,1,2],[1,2,1], and[2,1,1].
求数组元素的全排列,数组含重复元素。
【解题思路】在算法1的基础上,当我们枚举第i个位置的元素时,若要把后面第j个元素和i交换,则先要保证[i…j-1]范围内没有和位置j相同的元素,可以每次在需要交换时进行顺序查找。
【考查内容】递归,数组
class Solution {
public:
vector<vector<int> > permuteUnique(vector<int> &num) {
vector<vector<int> > res;
if(num.size() == 0)
return res;
vector<int> tmpres;
permuteRecur(num, 0, res, tmpres);
return res;
}
void permuteRecur(vector<int> &num, int index, vector<vector<int> >&res, vector<int>&tmpres){
if(index == num.size()){
res.push_back(tmpres);
return;
}
for(int i = index; i < num.size(); i++)
if(i == index || !find(num, index, i, num[i])){
swap(num[index], num[i]);
tmpres.push_back(num[index]);
permuteRecur(num, index+1, res, tmpres);
tmpres.pop_back();
swap(num[index], num[i]);
}
}
//从数组的[start,end)范围内寻找元素target
bool find(vector<int> &num, int start, int end, int target){
for(int i = start; i < end; i++)
if(num[i] == target)
return true;
return false;
}
};