1-n 全排列问题
1.非递归解法
思路 :利用数字下标从小增到最大,同一字符编同一数字
12345->12354->12435->12453->.....
find a[i]>a[i+1] , find j ,j>i && j<n && a[j]>a[i] && a[j+1]<a[i] ,swap a[i].a[j] ,reverse a[i ~ n]
function perm(str){ var n=str.length; var perm_start=[]; var start=1; var charIndex={}; for(var i=0;i<n;i++){ if(i==str.indexOf(str[i])){ charIndex[str[i]]=start++; } perm_start.push(charIndex[str[i]]); } var perm_strs=[]; var over=false; while(!over){ var tmpstr=[]; for(var i=0;i<perm_start.length;i++){ tmpstr.push(str[perm_start[i]-1]); } perm_strs.push(tmpstr); over=true; var i=n-1; for(i=n-1;i>0;i--) { if(perm_start[i]>perm_start[i-1]) { over=false; break; } } if(!over){ var minIndex=i; for(;minIndex<n;minIndex++) { if(perm_start[minIndex] < perm_start[i-1]){ break; } } minIndex--; var t=perm_start[i-1]; perm_start[i-1]=perm_start[minIndex]; perm_start[minIndex]=t; var right=perm_start.splice(i); right.reverse(); perm_start=perm_start.concat(right); } } return perm_strs; }
2.递归解法
思路:两两交换,穷尽所有可能
#include <iostream>
#include <iomanip>
#include <functional>
using namespace std;
template <typename T>
void Perm(T* List, int k, int m) {
int i;
if (k == m) {
for (i = 0; i <= m; i++) {
std::cout << List[i];
}
std::cout << std::endl;
}
else {
for (i = k; i <= m; i++) {
std::swap(List[k], List[i]);
Perm(List, k + 1, m);
std::swap(List[k], List[i]);
}
}
}
1-n 选出 m 个数组合问题
1.递归解法
思路:递归对前n-m个数考虑选和不选
/* select m from n */ function combination(m,n){ var result=[]; if(m==n){ for(var i=n;i>=1;i--){ result.push(i); } return [result]; } for(var i=n;i>=m;i--) { var sub=[i]; if(m==1) { result.push(sub); continue; } /* select one already,then select m-1 from n-1 */ var subs=combination(m-1,i-1); for(var j=0;j<subs.length;j++) { var tmp=sub.concat(subs[j]); result.push(tmp); } } return result; }