
排列组合去重算法挑战
方法一:抓取法
var permAlone=(function() {
var count; //计数器
function judge(arr) { //判断是否符合要求
for(let i=0,l=arr.length;i<l-1;i++){
if( arr[i]==arr[i+1] ){
return;
}
}
count++;
}
function fn(source, result) {
if (source.length == 0){
judge(result);
}else{
for (var i = 0; i < source.length; i++){
fn(source.slice(0, i).concat(source.slice(i + 1)), result.concat(source[i]));
}
}
}
return function(str){
var start=new Date();
var arr=str.split("");
count=0;
fn(arr, []);
console.log(new Date()-start+"ms");
return count;
};
})();
permAlone('abcdefa');
方法二:交换法
var permAlone=(function(){
var count; //计数器
function swap(arr,i,j) { //交换
if(i!=j) {
var temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
function fn(n,arr) { //为第n个位置选择元素
for(var i=n;i<arr.length;i++) {
swap(arr,i,n);
if( arr[n]==arr[n-1] ){ //和前一个元素比对,是否相等,只有前面的元素是固定不变的
swap(arr,i,n); //跳过前先复原
continue;
}
if(n<arr.length-1){ //判断条件这里需要改一下,只有当n为最后一个时才输出
fn(n+1,arr); //为序号n+1的位置选取值
}else{
if( arr[n]!=arr[n-1] ){
count++; //计数
}
}
swap(arr,i,n);
}
}
return function(str){
var start=new Date();
var arr=str.split("");
count=0; //计数器归零
fn(0,arr);
console.log(new Date()-start+"ms");
return count;
};
})();
permAlone('abcdefa');
方法三:
function permAlone(str) {
var arr = str.split(''),
rArr = [],
count = 0;
var swap = function (arr, i, j) {
if (i != j) {
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
};
(function fn(n) { //为第n个位置选择元素
for (var i = n; i < arr.length; i++) {
swap(arr, i, n);//换
if (n + 1 < arr.length - 1) //判断数组中剩余的待全排列的元素是否大于1个
{
fn(n + 1);//从第n+1个下标进行全排列
} else {
rArr.push(arr.join(''));
}
swap(arr, i, n);//复原
}
})(0);
count = rArr.length;
rArr.forEach(function (val) {
if (val.match(/([a-z]{1})\1/)) {
count--;
}
});
return count;
}
permAlone('aab');