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;
}

被折叠的 条评论
为什么被折叠?



