dlehdanakf / Codingtest-Study

알고리즘 코딩테스트 토막지식 정리
1 stars 0 forks source link

Set, PowerSet, Combination, Permutation #2

Open dlehdanakf opened 3 years ago

dlehdanakf commented 3 years ago

집합

const numeric = [ 1, 2, 3, 4, ... ];
const alphabet = [ 'a', 'b', 'c', 'd', ... ];

부분집합

모든 가능한 부분집합

const getAllSubsets = arr => arr
    .reduce((cur, acc) => [...cur, ...cur.map(set => [acc, ...set])], [[]]);

// 정렬된 버젼
const getAllSubsets = arr => arr
    .reduce((cur, acc) => [...cur, ...cur.map(set => [acc, ...set])], [[]])
    .map(cur => cur.sort((a, b) => a - b))
    .sort((a, b) => a.length - b.length);

n개 원소의 부분집합

const combinations = (set, k) => {
    const result = [];
    if (k > set.length || k <= 0) return [];
    if (k == set.length) return [set];
    if (k == 1) {
        for(let i = 0; i < set.length; i++) {
            result.push([ set[i] ]);
        }

        return result;
    }

    for(let i = 0; i < set.length - k + 1; i++) {
        const head = set.slice(i, i + 1);
        const tail = combinations(set.slice(i + 1), k - 1);
        for(let j = 0; j < tail.length; j++) {
            result.push([...head, ...tail[j]])
        }
    }

    return result;
};

각 배열에서 하나씩 원소를 빼내 조합하기

/** cartesian([1,2,3,4], ['a','b'], ['ㄱ', 'ㄴ', 'ㄷ']) */
const cartesian = (...args) => {
    const results = [], max = args.length - 1;
    const helper = (arr, i) => {
        for(let j = 0, l = args[i].length; j < l; j++) {
            const a = [...arr]
            a.push(args[i][j]);

            if(i === max) results.push(a);
            else helper(a, i + 1);
        }
    };

    helper([], 0);
    return results;
};

순열

const permutation = arr => {
    const result = [];
    arr.forEach((cur, i) => {
        const rest = permutation([...arr.slice(0, i), ...arr.slice(i + 1)]);
        if(rest.length === 0) result.push([ cur ]);
        else rest.forEach(m => result.push([ cur, ...m ]));
    });

    return result;
};