码迷,mamicode.com
首页 > 编程语言 > 详细

获取数组的子集数组

时间:2020-06-08 20:48:51      阅读:61      评论:0      收藏:0      [点我收藏+]

标签:元素   个数   concat   参数   获取   rev   targe   长度范围   数组元素   

一般算法结合数组的都逃不出数组的各种组合和过滤,组合完成了,过滤自然简单。
题目:根据一个数组求它的所有子数组集合。
如[1,2,3] => [1] [2] [3] [1,2] [1,3] [2,3] [1,2,3]
解法一: 以数组长度为维度,子数组的长度范围是1 至 arr.length,将每一轮长度的子集合并在一起即可。

var arr = [1,2,3,4,5,6,9];
var result = []
function getArrList(arr) {
    for (let i = 1; i <= arr.length; i++) {
        // getArrByLen 参数 arr: 原始数组、[]:上一轮结果、start:取item的起始位置、leftLength:目标数组的剩余空间
        getArrByLen(arr, [], 0, i)
    }
    return result
}

function getArrByLen(originArr, prevArr = [], start, leftLength) {
    for (let i = start; i < originArr.length; i++) {
        let target = clone(prevArr);
        let curLeft = leftLength
        target.push(originArr[i])
        if (--curLeft > 0) {
            getArrByLen(arr, clone(target), i + 1, curLeft)
        } else {
            result.push(target)
        }

    }
}

function clone(arr) {
    return [].concat(arr);
}

getArrList(arr)


解法二: 获取全部长度的子集

var arr = [1, 2, 3];

function desArr(arr) {
    if (arr.length == 0) {
        return []
    }
    var target = arr.shift()
    return add(desArr(arr), target)
}

function add(list, target) {
    for (var i = 0, len = list.length; i < len; i++) {
        var newItem = clone(list[i])
        newItem.push(target)
        list.push(newItem)
    }
    list.push([target])
    return list
}

function clone(arr) {
    return [].concat(arr);
}

console.log(desArr(arr))
总结:两种方法都离不开递归的思想,第一种方法相当于给数组加了挑选item的条件,从源数组的什么位置开始,上一轮结果是啥,剩余多少空间,如仍有多余空间则继续递归。第二种方法则是先将数组元素一个一个拆散,拆到最后为空数组开始重新组装,基于上次的数组重新循环添加新的元素,所以看add里list有两次push。一次是单个元素,一次则是该单个元素添加进上一轮结果的每个item里。

获取数组的子集数组

标签:元素   个数   concat   参数   获取   rev   targe   长度范围   数组元素   

原文地址:https://www.cnblogs.com/hjj2ldq/p/13068111.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!