排列组合-js

排列组合

数学相关知识:5分钟彻底了解排列组合

参考:程序员必备算法——排列组合

排列有序,组合无序

3选2 :排列个数:3*2 ;组合个数:3*2/2*1

选第一个元素时3种情况;在除去了第一个元素后,在剩下的元素中继续选出第二个元素,2种情况;

排列采取多分支递归的方式

单分支递归:

​ 递归的结束情况时返回计算值,最后一层递归之前的递归方法返回值是下一次递归的返回值 return recur()

所以整个递归的返回值是递归结束时计算出的结果

function recur (inputVal) {
  if (inputVal === 10) {
    return inputVal
  } else {
    return recur(++inputVal)
  }
}
console.log(recur(0)) // 10

多分支递归:

[1,2,3][A,B,C]两两组合,先选数字再选字母

由于是多分支,所以需要数组储存所有分支结果。在递归的终止条件时得到一个分支的结果,此时将结果.push()储存。每个分支都将结果储存到同一个数组 result中,所以for循环结束后返回result得到所有分支值。

function branchRecur (step, lastVal, result = []) {
  if (step === 0) {
    result.push(lastVal)
  } else {
    let data = [['A', 'B', 'C'],[1,2,3]]
    for (let i = 0; i < data.length; i++) {
      branchRecur(step - 1, lastVal + data[step - 1][i], result)
    }
    return result
  }
}
console.log(branchRecur(2,'')) //[ '1A', '1B', '2A', '2B' ]

排列:

每次从数组中选一个元素,可选情况为数组长度。将选了的数据从数组中剔除,下次再选一个元素,可选情况为数组长度。

function sequence (data, selectNum, lastVal, result) { // 排列
    /*
    data:Array;供选择的数据
    selectNum:num;选择多少个数据
    lastVal:string;初始值为‘’;初始值为''
    result:Array;初始值为[];整个排序的结果
    */
  if (selectNum === lastVal.length || !data.length) {
    result.push(lastVal)
  } else {
    // 每次在剩下的data中选一个值
    for (let i = 0; i < data.length; i++) {
      let newData = [].concat(data)
      newData.splice(i, 1)
      sequence(newData, selectNum, lastVal + data[i], result)
    }
    return result
  }
}
console.log(sequence([1, 2, 3], 2, '', [])) //[ '12', '13', '21', '23', '31', '32' ]

组合:

从数组中[1,2,3]依次选取元素,每个元素都可选可不选,一共2^3中选项。其中选了2个元素的有3种

function combine (data, lastVal, result = []) {
  if (!data.length) {
    result.push(lastVal)
    return
  }
  let newData = [].concat(data)
  let item = newData.shift()
  combine(newData, lastVal + item, result) // 选
  combine(newData, lastVal, result) // 不选
  return result
}
console.log(combine([1, 2, 3], '')) //[ '123', '12', '13', '1', '23', '2', '3', '' ]

所以加以限制条件,3选2,选到2个也为递归终止条件,当data长度为0时也终止递归,但是要舍弃没有选到两个数的结果

function combine (data, selectNum, lastVal, result = []) {
  if (lastVal.length === selectNum || !data.length) {
    lastVal.length === selectNum && result.push(lastVal)
    return
  }
  let newData = [].concat(data)
  let item = newData.shift()
  combine(newData, selectNum, lastVal + item, result) // 选
  combine(newData, selectNum, lastVal, result) // 不选
  return result
}
console.log(combine([1, 2, 3], 2, '')) // [ '12', '13', '23' ]
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,509评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,806评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,875评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,441评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,488评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,365评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,190评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,062评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,500评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,706评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,834评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,559评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,167评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,779评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,912评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,958评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,779评论 2 354

推荐阅读更多精彩内容