包括了排列,组合,子集问题,子集带重复问题,基本全了,就差在看看leetcode以前怎么写的了
1 //全排列的两种方法 2 #include <iostream> 3 #include <vector> 4 #include <algorithm> 5 using namespace std; 6 7 //方法一,采用swap方法 8 void quanpailie(char * A,int first,int n) 9 { 10 if(A==NULL) 11 { 12 cout<<"A is NULL"<<endl; 13 return; 14 } 15 if(n<=1) 16 { 17 cout<<A<<endl; 18 return; 19 } 20 for(int i=first;i<first+n;i++) 21 { 22 swap(A[i],A[first]); 23 quanpailie(A,first+1,n-1); 24 swap(A[i],A[first]); 25 } 26 return; 27 } 28 29 //采用字典序全排序,就是采用的字典排序思想,从后向前找出第一个A[i]<A[i+1],如果没有就说明结束, 30 //然后在从右向左找出第一个大于A[i]的,进行交换,然后逆序i+1到最后(也就是逆序j到最后)。 31 void quanpailie2(char * A,int n) 32 { 33 cout<<A<<endl; //输出最开始的“abc” 34 if(A==NULL||n<=0) 35 return; 36 while(true) 37 { 38 int i; 39 for(i=n-2;i>=0;i--) 40 { 41 if(A[i]<A[i+1]) 42 break; 43 } 44 if(i<0) 45 { 46 break; 47 } 48 for(int k=n-1;k>=0;k--) 49 { 50 if(A[k]>A[i]) 51 { 52 swap(A[i],A[k]); 53 break; 54 } 55 } 56 reverse(A+i+1,A+n); 57 cout<<A<<endl; 58 } 59 } 60 61 /* 62 子集问题,子集问题有两种情况,比如正常的{1,2,3}求子集就是{},{1},{2},{3},{1,2},{1,3},{2,3},{1,2,3} 63 还有就是有重复的情况比如{1,2,2}求子集就是{},{1},{2},{1,2},{2,2},{1,2,2} 64 注意区分子集问题和组合问题,组合问题为最简单的递归回溯问题1,2,3,4,选2个为{1,2},{1,3},{1,4},{2,3},{2,4},{3,4},{3,4} 65 */ 66 67 //组合问题(子集问题),方法一,采用vector,比较取巧,完全不计较空间的解法了,这个是全组合问题给你abc返回 68 //{},{a},{b},{c},{a,b},{a,c},{b,c},{a,b,c},注意和C(n,k)的区别 69 //最简单情况,没有重复的方法一,{1,2,3} 70 void subsets(char *A ,int n,vector<vector<char>> &result) 71 { 72 vector<char> tmp; //空vector 73 result.push_back(tmp); 74 for(int i=0;i<n;i++) 75 { 76 int size=result.size(); //注意,必须提前村上size,不然每次result.size()都是新的 77 for(int j=0;j<size;j++) 78 { 79 vector<char> t=result[j]; //必须用个临时的新的,否则会更改result[j]的值。 80 t.push_back(A[i]); //注意是push_back(A[i]) 81 result.push_back(t); 82 } 83 } 84 //最后result里面有一个空的 85 //result.erase(result.begin()); //或者不删除也行,在显示的时候也可以不显示,但会多打出一个换行符 86 /*for(int i=0;i<result.size();i++) 87 { 88 for(int j=0;j<result[i].size();j++) 89 { 90 cout<<result[i][j]; 91 } 92 cout<<endl; 93 }*/ 94 } 95 96 //子集问题,方法二,采用递归方法,也是普通的{1,2,3,4} 97 void subsets2(char *A,int n,int first,vector<vector<char>> &result,vector<char> &tmp) 98 { 99 result.push_back(tmp); 100 for(int i=first;i<n;i++) 101 { 102 tmp.push_back(A[i]); 103 subsets2(A,n,i+1,result,tmp); 104 tmp.pop_back(); 105 } 106 107 } 108 109 110 //子集问题,特殊的情况处理如{1,2,2}这种情况的子集,方法一,也是迭代方法,只不过加了去重的思想 111 112 void subsets_without_repeat(char *A ,int n,vector<vector<char>> &result) 113 { 114 sort(A,A+n);//注意必须先排序 115 vector<char>tmp; 116 result.push_back(tmp); 117 int size,pre_size,j; 118 for(int i=0;i<n;i++) 119 { 120 size=result.size(); 121 if(i-1>=0&&A[i]==A[i-1]) //如果重复了,就让j是从上次的size开始,注意初始判断i-1>=0 122 j=pre_size; 123 else 124 j=0; 125 while(j<size) 126 { 127 vector<char> t=result[j]; 128 t.push_back(A[i]); 129 result.push_back(t); 130 j++; 131 } 132 pre_size=size; //记录上次的size 133 } 134 } 135 136 /*子集问题,特殊的情况处理如{1,2,2}这种情况的子集,方法二,也是采用递归方法,只不过加了去重的思想,去重的思路是{1,2,2}, 137 当是{},{1},{1,2},{1,2,2},tmp原来是{1,2},然后弹出2,tmp是{1},下一个元素是第二个2时,这个就可以跳过了,不用再有{1,2}了,然后1弹出 138 2入为{2},即i!=first&&A[i]==A[i-1]就可以跳过了 139 */ 140 void subsets_without_repeat2(char *A,int n ,int first,vector<vector<char>> & result,vector<char> & tmp) 141 { 142 result.push_back(tmp); 143 for(int i=first;i<n;i++) 144 { 145 if(i!=first&&i-1>=0&&A[i]==A[i-1]) 146 continue; 147 tmp.push_back(A[i]); 148 subsets_without_repeat2(A,n,i+1,result,tmp); 149 tmp.pop_back(); 150 } 151 } 152 153 154 /* 155 组合问题,C(n,k)问题,很容易,用递归回溯的典型,1,2,3,4 ,给定n为4,k=2,则{1,2},{1,3},{1,4},{2,3},{2,4},{3,4} 156 */ 157 void compose(char *A,int n,int start,int dep,vector<vector<char>> &result,vector<char> &tmp) 158 { 159 if(A==NULL||n<=0) 160 return; 161 if(dep==2) 162 { 163 result.push_back(tmp); 164 return; 165 } 166 for(int i=start;i<n;i++) 167 { 168 tmp.push_back(A[i]); 169 compose(A,n,i+1,dep+1,result,tmp); 170 tmp.pop_back(); 171 } 172 } 173 174 int main() 175 { 176 char A[]="1234"; 177 vector<vector<char>> result; 178 vector<char> tmp; 179 //quanpailie(A,0,4); 180 //quanpailie2(A,4); 181 //subsets(A,3,result); 182 //subsets2(A,4,0,result,tmp); 183 //subsets_without_repeat(A,3,result); 184 //subsets_without_repeat2(A,3,0,result,tmp); 185 compose(A,4,0,0,result,tmp); 186 for(int i=0;i<result.size();i++) 187 { 188 for(int j=0;j<result[i].size();j++) 189 { 190 cout<<result[i][j]; 191 } 192 cout<<endl; 193 } 194 system("pause"); 195 }