작성자: 조광형
작성일: 2024년 11월 26일
문제 설명
동전으로 거슬러 줄 수 있는 최소 개수를 계산하는 문제입니다. 여러분은 주어진 동전의 종류와 총액을 기반으로 해서 동전을 최소 개수로 사용하여 총액을 만드는 방법을 찾아야 합니다. 동전의 종류는 무한히 많다고 가정합니다.
예를 들어, 동전의 종류가 {1, 5, 10, 25} 동전이 있고, 만들어야 하는 총액이 63일 때, 여러분은 최소 몇 개의 동전을 사용해야 할지를 찾아야 합니다.
입력
- coinValues: 동전의 종류를 나타내는 정수 배열 (예: [1, 5, 10, 25])
- amount: 총액을 나타내는 정수 (예: 63)
출력
- 최소 동전 개수를 반환합니다. 만약 금액을 만들 수 없는 경우에는 -1을 반환합니다.
문제 접근 방식
이 문제는 동적 프로그래밍(Dynamic Programming) 기법을 사용하여 해결할 수 있습니다. 동적 프로그래밍은 문제를 작은 부분문제로 나누고, 이러한 작은 문제들의 해답을 조합하여 전체 문제의 해결책을 찾아가는 방식입니다. 이 문제를 풀기 위해 다음과 같은 단계를 따르겠습니다.
- DP 테이블 초기화: 동전을 사용하여 만들 수 있는 각 금액에 대해 최소 동전 개수를 기록하는 DP 테이블을 만듭니다.
- 기본 케이스 설정: DP 테이블의 0 번째 인덱스(0원)는 동전이 필요 없으므로 0으로 설정합니다.
- 이전 결과 활용: 각 동전에 대해 가능한 금액을 계산하며 DP 테이블을 갱신합니다.
- 결과 반환: lowest number of coins to make the required amount, or -1 if it’s impossible.
자바스크립트 코드 구현
function coinChange(coinValues, amount) {
// DP 테이블 초기화
const dp = Array(amount + 1).fill(Infinity);
dp[0] = 0; // 0원을 만들기 위한 동전의 수는 0
// 각 동전을 하나씩 확인
for (let coin of coinValues) {
for (let j = coin; j <= amount; j++) {
dp[j] = Math.min(dp[j], dp[j - coin] + 1);
}
}
// 결과 반환
return dp[amount] === Infinity ? -1 : dp[amount];
}
이 코드는 주어진 coinValues 배열과 amount를 가지고 DP 테이블을 작성하고, 최소 동전의 개수를 계산합니다.
동작 과정 설명
위의 코드는 여러 단계로 구성되어 있으며, 이를 통해 동전의 개수를 최소화하는 방법을 살펴보겠습니다.
1단계: DP 테이블 초기화
const dp = Array(amount + 1).fill(Infinity);
이 코드는 일정한 길이의 배열을 생성하며 모든 값을 무한대로 초기화합니다.
이후 dp[0] = 0;
으로 0원을 만드는 데 필요한 동전 개수를 0으로 설정합니다.
2단계: 각 동전으로 금액 갱신
for (let coin of coinValues)
구문으로 각 동전에 대해 반복하며 가능한 금액을 계산합니다.
중첩된 for
문에서 dp[j] = Math.min(dp[j], dp[j - coin] + 1);
를 통해 각 금액에 대한 최소 동전 개수를 갱신합니다.
3단계: 결과 반환
마지막으로 return dp[amount] === Infinity ? -1 : dp[amount];
를 통해 해당 금액을 만들 수 없는 경우 -1을 반환합니다. 만들 수 있는 경우 최소 동전 개수를 반환합니다.
예제와 테스트 케이스
예제 1
입력: coinValues = [1, 5, 10, 25], amount = 63
출력: 6
해설: 25, 25, 10, 1, 1, 1로 총 6개의 동전을 사용하여 63을 만들 수 있습니다.
예제 2
입력: coinValues = [2], amount = 3
출력: -1
해설: 2만 사용해서는 3을 만들 수 없습니다.
예제 3
입력: coinValues = [1], amount = 0
출력: 0
해설: 0원을 만들기 위해서 필요한 동전은 없습니다.
이 코드의 시간 복잡도와 공간 복잡도
이 알고리즘의 시간 복잡도는 O(n * m)입니다. 여기서 n은 동전의 종류 수, m은 목표 자금입니다. DP 테이블을 작성하고 갱신하는 데 O(m) 작업이 동전 수만큼 반복되므로 이 복잡도를 가집니다.
공간 복잡도는 O(m)입니다. 이는 동전 갯수에 대해 동적으로 생성된 DP 테이블 때문입니다.
마무리
이 글에서는 자바스크립트를 사용하여 동전 개수의 최솟값을 구하는 문제를 동적 프로그래밍을 통해 해결하는 방법을 다루었습니다.
문제를 제공한 뒤 다양한 해법과 코드 구현을 통해 주제를 심층적으로 살폈습니다.
이러한 알고리즘은 실제 면접에서도 자주 출제되므로 잘 익히는 것이 좋습니다.
앞으로의 코딩테스트 준비에 도움이 되길 바랍니다!