獲取數組的子集數組


一般算法結合數組的都逃不出數組的各種組合和過濾,組合完成了,過濾自然簡單。
題目:根據一個數組求它的所有子數組集合。
如[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里。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM