数字的排列问题。分别为没有重复数字和有重复数字的情况。第一种情况为基础,第二种情况要考虑去重。都采用DFS【深度优先搜索(Depth-First-Search)】。
Permutations:
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]
.
递归的思想。把数组看成两个部分,第一部分为第一个数字,第二部分为剩下的所有数字。求整个数组的排列,可以看成两步:首先求所有可能出现在第一个位置的数字,即把第一个数字和所有后面的数字交换。第二步是固定第一个数字,求后面所有数字的排列。这个时候仍然把后面的所有数字分成两个部分,即可实现递归。
代码如下:
class Solution {
public:
vector<vector<int> > permute(vector<int> &num) {
vector<vector<int>> result;
if (num.size() == 0)
return result;
sort(num.begin(), num.end());
permute(num, 0, result);
return result;
}
private:
void permute(vector<int> &num, size_t start, vector<vector<int>> &result){
if (start == num.size()-1){
result.push_back(num);
}
else{
for (size_t i = start; i < num.size(); i++){
swap(num[start], num[i]);
permute(num, start + 1, result);
swap(num[start], num[i]);
}
}
}
};
Permutations 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]
.
代码如下:
class Solution {
public:
vector<vector<int> > ans;
vector<vector<int> > permuteUnique(vector<int> &num) {
sort(num.begin(),num.end());
dfs(num,0);
return ans;
}
void dfs(vector<int> &num,int start) {
if(start == num.size()) {
ans.push_back(num);
return;
}
for(int i = start;i < num.size();i++) {
//skip duplicate,if the element have emerge before,skip this one!!!
bool skip = false;
for(int j = start;j < i;j++) {
if(num[j] == num[i]) {
skip = true;
break;
}
}
if(skip)
continue;
//if before have be meeted,so skip this???maybe hashtable will be more efficient???
swap(num[i],num[start]);
dfs(num,start+1);
swap(num[i],num[start]);
}
}
};