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 > permute(vector &num) {
}
};
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
方法一:利用上述写的next permutation 的程序,此时Permutation和Permutation II一样,不管数组中是否有元素重复
class Solution {
public:
vector > permute(vector &num) {
vector> result;
sort(num.begin(), num.end());
result.push_back(num);
while(nextPermute(num)){
result.push_back(num);
}
return result;
}
bool nextPermute(vector &num){
int i = num.size() - 1;
for(; i > 0; i--){
if(num[i] > num[i-1]) break;
}
if(i == 0) return false;
int min = INT_MAX;
int minIndex = i;
int tmp = num[i-1];
for(int j = i+1; j <= num.size() - 1; j++){
if(num[j] > tmp && num[j] < min){
minIndex = j;
min = num[j];
}
}
swap(num[i-1], num[minIndex]);
sort(num.begin() + i, num.end());
return true;
}
};
方法二:暴力搜索法,递归
class Solution {
public:
vector > permute(vector &num) {
vector> result;
vector path;
dfs(result, path, num);
return result;
}
void dfs(vector> &result, vector &path, vector &num){
if(path.size() == num.size()){
result.push_back(path);
return;
}
for(auto nn : num){
if(find(path.begin(), path.end(), nn) == path.end()){
path.push_back(nn);
dfs(result, path, num);
path.pop_back();
}
}
}
};
----------------------------------------------------------------------------------------------------------------------------------------------
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 > permuteUnique(vector &num) {
}
};
------------------------------------------------------------------------------------------------------------------------------------------------------------------
方法一:利用上述写的next permutation 的程序,此时Permutation和Permutation II一样,不管数组中是否有元素重复
class Solution {
public:
vector > permuteUnique(vector &num) {
vector> result;
sort(num.begin(), num.end());
result.push_back(num);
while(nextPermute(num)){
result.push_back(num);
}
return result;
}
bool nextPermute(vector &num){
int i = num.size() - 1;
for(; i > 0; i--){
if(num[i] > num[i-1]) break;
}
if(i == 0) return false;
int min = INT_MAX;
int minIndex = i;
int tmp = num[i-1];
for(int j = i+1; j <= num.size() - 1; j++){
if(num[j] > tmp && num[j] < min){
minIndex = j;
min = num[j];
}
}
swap(num[i-1], num[minIndex]);
sort(num.begin() + i, num.end());
return true;
}
};
方法二:暴力搜索法,递归
统计词频,迭代~
class Solution {
public:
vector > permuteUnique(vector &num) {
vector> result;
n = num.size();
unordered_map count_map;
for(int i = 0; i < num.size(); i++){
if(count_map.find(num[i]) == count_map.end()){
count_map[num[i]] = 1;
}else{
count_map[num[i]]++;
}
}
vector path;
dfs(result, path, count_map);
return result;
}
size_t n;
void dfs(vector> &result, vector &path, unordered_map count_map){
if(path.size() == n){
result.push_back(path);
return;
}
for(auto it = count_map.begin(); it != count_map.end(); it++){
int count = 0;
for(int j = 0; j < path.size(); j++){
if(path[j] == it->first) count++;
}
if(count < it->second){
path.push_back(it->first);
dfs(result, path, count_map);
path.pop_back();
}
}
}
};
注:要从count_map的元素来迭代,因为其中无重复元素。。。num中有重复元素
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Permutation Sequence
The set [1,2,3,…,n]
contains a total of n! unique permutations.
By listing and labeling all of the permutations in order,
We get the following sequence (ie, for n = 3):
-
"123"
-
"132"
-
"213"
-
"231"
-
"312"
-
"321"
Given n and k, return the kth permutation sequence.
Note:
Given
n
will be between 1 and 9 inclusive.
class Solution {
public:
string getPermutation(int n, int k) {
}
};
--------------------------------------------------------------------------------------------------------------------------------------------------------
方法一,
利用上述写的next permutation 的程序,此时Permutation和Permutation II一样,不管数组中是否有元素重复
class Solution {
public:
string getPermutation(int n, int k) {
int tolNum = 1;
string sInit = "";
for(int i = 1; i <= n; i++){
tolNum *= i;
char tmp = '0'+i;
sInit.insert(sInit.end(), tmp);
}
k = k % tolNum;
if(k == 0) k = tolNum;
while(--k){
sInit = nextPermutation(sInit);
//cout<<sInit<<endl;
}
return sInit;
}
string nextPermutation(string &ss){
int i = ss.size() - 1;
for(; i > 0; i--){
if(ss[i] > ss[i-1]) break;
}
if(i == 0 ) {
sort(ss.begin(), ss.end());
return ss;
}
int minIndex = i;
for(int j = i+1; j < ss.size(); j++){
if(ss[j] > ss[i-1] && ss[j] < ss[minIndex]){
minIndex = j;
}
}
swap(ss[minIndex], ss[i-1]);
sort(ss.begin() + i, ss.end());
return ss;
}
};
方法二,康托编码:
原始字符串:123456789,从小到大排序
新的字符串:a1a2a3a4a5... ,假设长度为n,则(a2a3a4...),长度为n-1,有(n-1)!种排列
求第K个排列~~~"1234...n"为第1个排列
k = k-1;转换为从0开始,方便之后计算,原来是k从1开始
pos1 = k/(n-1)!
第k个排列的第1个字符为,原始字符串中pos1位置的字符
k = k%(n-1)!
更新k
pos2 = k/(n-2)!;
第k个排列的第2个字符为,原始字符串中pos2位置的字符
k = k%(n-2)!
更新k
依次循环,求出新的字符串,共n位,n次循环
class Solution {
public:
string getPermutation(int n, int k) {
string sInit = "";
for(int i = 1; i <= n; i++){
char tmp = '0' + i;
sInit.insert(sInit.end(), tmp);
}
return getPermutation(sInit, k);
}
int f(int n){
int result = 1;
for(int i = 1; i <= n; i++){
result = result * i;
}
return result;
}
string getPermutation(string &sInit, int k){
string sResult = "";
k--;
int len = sInit.size();
for(int i = 0; i <= len - 1; i++){
int pos = k/f(len - 1 - i);
sResult.insert(sResult.end(), sInit[pos]);
sInit.erase(sInit.begin() + pos);
k = k % f(len - 1 - i);
}
return sResult;
}
};
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
最偷懒的方法:利用STL里的next_permutation函数
vector num
bool next_permutation(num.begin(), num.end())
返回值是布尔类型,同时改变num中的值