全排列生成 Permutations

来源:互联网 发布:js table 可编辑 编辑:程序博客网 时间:2024/05/22 03:45

题目: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> > v;        ProduceArray(num, 0, v);        return v;    }void ProduceArray(vector<int> data, int index, vector<vector<int> > &v)  {  int n = data.size();    if(index == n)      {          v.push_back(data);        return;    }      for(int i=index;i < n;i++)      {          swap(data[i], data[index]);          ProduceArray(data, index+1, v);          swap(data[i], data[index]);      }}};
注意:这种方法的缺点是如果序列中有重复元素,得到的排列也是有重复的。


思路二:第一种方法的思路是交换,第二种方法的思路就是插入。首先拿出原序列的第一个元素,然后将其插入到剩余序列中,有n种插入方法(得到的序列个数是原来的n倍)。递归地,剩余序列也可以这么做而得到。这也可以看作是一种分治策略,即把规模为N的原问题分解为规模为1的问题和规模为N的问题。

代码:

#include <iostream>#include <string>#include <vector>using namespace std;string insertCharAt(const string &word, char c, int i){    if(i<0 || i > word.size())        return word;    string left = word.substr(0, i);    string right = word.substr(i);        return left + c + right;}vector<string> genPermutation(const string &s){    vector<string> re;    if(s.size() == 1)    {        re.push_back(s);        return re;    }    char first = s[0];    string rest = s.substr(1);    vector<string> restwords = genPermutation(rest);        vector<string>::iterator it = restwords.begin();    for( ;it != restwords.end();it++)    {        for(int i=0;i<=(*it).size();i++)        {            re.push_back(insertCharAt((*it), first, i));        }    }    return re;}int main(int argc, const char * argv[]){    string s = "abc";    vector<string> permutation = genPermutation(s);    cout<<permutation.size()<<endl;    vector<string>::iterator it = permutation.begin();    for(; it != permutation.end();it++)        cout<<(*it)<<endl;    return 0;}

思路三(有重复元素):先利用hash给每种不同的数做计数统计,然后用backtrack方法。需要辅助空间。

class Solution {public:    vector<vector<int> > permuteUnique(vector<int> &num) {        vector<vector<int> > v;        int n = num.size();        if(n == 0)            return v;                    map<int, int> m;        for(int i=0;i<n;i++)            if(m.find(num[i]) == m.end())                m[num[i]] = 1;            else                m[num[i]]++;                vector<int> now;        backtrack(m, v, num, n, now, 0);        return v;    }        void backtrack(map<int, int> &m, vector<vector<int> > &v, vector<int> &num, int n, vector<int> now, int idx)    {        if(idx == n)        {            v.push_back(now);            return;        }        map<int, int>::iterator it = m.begin();        for(;it != m.end(); it++)        {            if((*it).second > 0)            {                (*it).second--;                now.push_back((*it).first);                backtrack(m, v, num, n, now, idx+1);                (*it).second++;                now.pop_back();            }        }    }};