将n个元素按照一定的顺序排列起来,求出排列的所有组合。
算法分析, 假定n个元素的全排列组合为F(n)
1. n = 1,只有一种组合(1),即F(n) = [(1)];
2. n = k时,只需要与n = k - 1时形成的全排列组合F(k - 1)一一组合排列即可,增加的元素为 (k - 1) * F(k - 1),故现在的组合数量为 (k - 1) * F(k - 1) + F(k - 1) = k * F(k - 1);
算法复杂度,显然为n的阶乘n!。
算法实现(javascript):
1. n = 1时,返回[[1]];
2. n = k时,返回 k 与 F(k - 1)集合的排列组合;
function sequance(n) {
if(n == 1) {
// 退出递归
return [[1]]
} else {
var sn = sequance(n-1),
result = []
for(var i = 0, len = sn.length; i < len; i ++) {
for(var j = 0; j < n; j ++) {
// 复制元素
var c = sn[i].slice();
// 在数组的每个位置都插入元素
c.splice(j, 0, n)
result.push(c)
}
}
return result;
}
}
尾递归实现方式如下:
/**
* rs 用于保存结果
* n 用于控制深度
*/
function sequance(n, rs) {
if(n > 0) {
var len = rs.length,
result = [];
if(len == 0) {
result.push([n])
} else {
for(var i = 0; i < len; i ++) {
for(var j = 0, ilen = rs[i].length; j <= ilen; j++) {
var c = rs[i].slice();
c.splice(j, 0, n)
result.push(c)
}
}
}
// 不再返回结果里进行结算,避免过多的压栈与出栈操作
return seq(n-1, result)
}
return rs
}
结论
采用数组作为输出结果,在n增大时,对内存的要求会急剧增加,导致出现内存溢出错误,所以需要一种更优化的解决方案(正在思考中)。