数组类算法题:卡牌分组(JS版本)

下面是卡牌分组题目,原题详见LeetCode卡牌分组
数组类算法题:卡牌分组(JS版本)_第1张图片
数组类算法题:卡牌分组(JS版本)_第2张图片
数组类算法题:卡牌分组(JS版本)_第3张图片

算法步骤:

step1.统计重复卡牌的数量。
step2.利用递归求出两种卡牌的最大公约数。
step3.同理,求出所有卡牌的最大公约数。
step4.得到结果。若最终的最大公约数大于1,说明卡牌可以分组。

源代码card_combination.js:

export default (arr)=>{
  //step1.利用reduce()求得重复的卡牌数量
  let objRepeat = arr.reduce(function(prev,next){
    prev[next] = (prev[next]+1)||1;
    return prev;
  },{});

  var cardGroup = Object.values(objRepeat);//用于存储卡牌重复的数目

  //step2.求得两种卡牌之间的最大公约数
  //源自y=ax与y=ax+b
  let gcd = (a, b) => {
    if (b === 0) {
      return a
    } else {
      return gcd(b, a%b);
    }
  }

  //step3.求得所有卡牌的最大公约数
  while(cardGroup.length>1){
    let first = cardGroup.shift();
    let second = cardGroup.shift();
    console.log(first,second);
    let result = gcd(first,second); //求得两张卡牌得最大公约数
    if(result===1){
      return false; //说明最大公约数是1
    }else{
      //将求得的公约数放回去,判断其余卡牌的公约数是否是该公约数。其中'0'不是唯一的,可以任意数值。主要是要判断length
      cardGroup.unshift(result);
    }
  }
  // step4.得出结论。若最终的最大公约数大于1,说明卡牌可以分组。
  return cardGroup.length?cardGroup[0]>1:false;//全部卡牌的最大公约数已经求完,判断最终的最大公约数是都大于1
}

测试代码card_combination.test.js:

import cardCombination from '../../src/chapter2_array/card_combination';

test('卡牌分组',()=>{
  expect(cardCombination([1,1,2,2,2,2])).toEqual(true);
})

经测试,本算法能得到示例中所有的输出结果。具体效果,请自行测试。

本算法基于jest测试工具进行测试,教程详见使用Jest测试JavaScript

你可能感兴趣的:(算法,算法JS版本,数组类算法,卡牌分组)