알고리즘 문제를 풀다가, 어떤 숫자 배열에 있는 원소를 조합하여 만들 수 있는 수 중 가장 큰 숫자 라던가 하는 순열, 조합 개념이 들어간 문제를 만났다. 구현하고 탐구해보기로 했다.
reduce
와 재귀호출을 사용해서 각 배열의 원소마다 순회하고 결과를 합친다.- 이미 순회한 것을
basket
에 넣는다 (들른 장소를 표시)- 순회조건을 설정한다
- 종료조건
function initializeNumbers(n) {
return Array(n).fill().map((_, idx) => idx + 1);
}
What 원소가 중복되지 않도록 한다
How filter
에서 이미 순회한 원소를 다시 순회하지 않도록 함수를 준다.
function permutation(
n, r, basket = [], arr = initializeNumbers(n),
) {
if (basket.length === r) {
return 1;
}
return arr
.filter((el) => !basket.includes(el)) // 순회 조건 설정
.reduce((acc, curr) => acc + permutation(n, r, basket.concat(curr), arr), 0);
}
test('permutation', () => {
expect(permutation(5, 3)).toBe(60);
expect(permutation(10, 3)).toBe(720);
});
What 순회 순서를 무시한다
How filter
에서 순회 방향을 한가지로 정한다. 이전 원소가 다음 원소 보다 크다, 혹은 작다.
function combination(
n, r, basket = [], arr = initializeNumbers(n),
) {
if (basket.length === r) {
return 1;
}
return arr
.filter((el) => el > Math.max(...basket)) // 순회 조건 설정
.reduce((acc, curr) => acc + combination(n, r, basket.concat(curr), arr), 0);
}
test('combination', () => {
expect(combination(5, 3)).toBe(10);
expect(combination(10, 3)).toBe(120);
});