生成組合數
舉例:ios
好比有一個數組`int arr[3] = {1,4,8} `,生成組合數就是要生成`{1},{4},{8},{1,4},{1,8},{4,8},{1,4,8}`
思路:數組
要生成`{1,4,8}`這個數組的組合數,須要依賴`{1,4}`的組合數。若是記`{1,4}`的生成的組合數集合爲A,那麼生成`{1,4,8}`的組合數的方式爲拷貝一份A序列集合獲得B序列集合,對B序列集合中全部的序列,都加上一個8,那麼`{1,4,8}`的序列結合就能夠用`A+B+{8}`的方式表示。`{1,4}`也是相似的過程。由`{1}`加上`{1,4}`以及`{4}`構成。
實現:spa
class Solution { public: //arr 數組指針 //len 數組長度 //返回二維數組 vector<vector<int> > getAllCombination(int arr[], int len) { vector<vector<int> > combinations; vector<int> a; a.push_back(arr[0]); combinations.push_back(a); for (int i = 1; i < len; i++) { unsigned long l = combinations.size(); for (unsigned long j = 0; j < l; j++) { vector<int> temp = combinations[j]; temp.push_back(arr[i]); combinations.push_back(temp); } vector<int> b; b.push_back(arr[i]); combinations.push_back(b); } return combinations; } }; int main() { int arr[] = {1, 4, 8}; Solution s = Solution(); vector<vector<int> > c = s.getAllCombination(arr,3); for(int i = 0;i<c.size();i++){ for(int j = 0;j<c[i].size();j++){ cout << c[i][j] << "\t"; } cout <<endl; } }
生成組合數
舉例:指針
生成排列數的過程,一樣是上面的列子`{1,4,8}`對應的組合數序列就是`{1},{4},{8},{1,4},{4,1},{1,8},{8,1},{4,8},{8,4},{1,4,8},{1,8,4},{4,1,8},{4,8,1},{8,1,4},{8,4,1}`一共是15種。
思路:code
生成排列數序列與組合數序列最大的不一樣就是排列數序列是有序的,而組合數序列是無序的,那麼排列數序列的生成就須要組合數序列、以及對這些組合數序列進行全排序。全排序就是對於`{1,4}`要生成`{1,4}`與`{4,1}`.組合數上面講過了,下面講下如何根據給定集合生成全排序。
生成全排序:排序
考慮已經有序列`abc`,那麼生成全排序以下: step1:對序列`abc`,經過將a與b、c交換獲得`bac`和`cba`.或者交換b和c獲得`acb`; step2:對`bac`又能夠交換a與c獲得`bca`;對`cba`交換b與a能夠獲得`cab`。 這樣咱們就能夠獲得`abc`的全排序。這樣一個過程就是不斷交換元素,可是須要控制好交換的開始座標以及結束條件。
全序列實現:get
class Solution{ public: vector<vector<int> >p; void permutation(int *arr,int start,int len){ if(start == len-1){ //根據當前序列構造序列 vector<int> temp; for(int i = 0;i<len;i++){ temp.push_back(arr[i]); } p.push_back(temp); } for(int i = start;i<len;i++){ swap(arr[start],arr[i]); permutation(arr,start+1,len); swap(arr[i],arr[start]); } } }; int main(){ int arr[] = {1,4,8}; Solution s = Solution(); s.permutation(arr,0,3);//s.p保存着全序列 for(int i = 0;i<s.p.size();i++){ for(int j = 0;j<s.p[i].size();j++){ cout << s.p[i][j] << "\t"; } cout << endl; } }
排列數生成:
最後咱們來生成排列數序列。就兩步,首選生成組合數序列,其次對於每一個組合數序列,利用上面的全序列的生成過程生成每一個組合序列的全序列,把全部的全序列合在一塊兒,就能夠獲得咱們的排列數序列。io
實現:class
#include <iostream> #include <vector> using namespace std; class Solution{ public: //構造組合數 vector<vector<int> > getAllCombination(int arr[],int len){ vector<vector<int> >ret; vector<int>a; a.push_back(arr[0]); ret.push_back(a); for(int i = 1;i<len;i++){ unsigned long l = ret.size(); for(int j = 0;j<l;j++){ vector<int> temp = ret[j]; temp.push_back(arr[i]); ret.push_back(temp); } vector<int>b; b.push_back(arr[i]); ret.push_back(b); } return ret; } vector<vector<int> >p; //生成全序列 void getPermutation(int arr[], int start, int len){ if(start == len-1){ //顯示、保存全序列 vector<int> temp; for(int i = 0;i<len;i++){ temp.push_back(arr[i]); } p.push_back(temp); } for(int i = start;i<len;i++){ swap(arr[start],arr[i]); getPermutation(arr,start+1,len); swap(arr[start],arr[i]); } } vector<vector<int> > getAllPermutation(int arr[], int len){ vector<vector<int> > ret; vector<vector<int> > combinations = getAllCombination(arr,len); for(int i = 0;i<combinations.size();i++){ int tempArr[combinations[i].size()]; for(int j= 0;j<combinations[i].size();j++){ tempArr[j] = combinations[i][j]; } p.clear(); getPermutation(tempArr,0,combinations[i].size()); //ret.insert(ret.end(),p.begin(),p.end()); for(int j = 0;j<p.size();j++){ ret.push_back(p[j]); } } return ret; } }; int main(){ int arr[] = {1,4,8}; Solution s = Solution(); vector<vector<int> > r = s.getAllPermutation(arr,3); for(int i = 0;i<r.size();i++){ for(int j= 0;j<r[i].size();j++){ cout << r[i][j] << "\t"; } cout << endl; } return 0; }