[프로그래머스] 줄 서는 방법 Lv2
2025. 2. 15. 15:00ㆍ코딩 테스트 준비
728x90
반응형
https://school.programmers.co.kr/learn/courses/30/lessons/12936
프로그래머스
SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
function solution(n, k) {
const answer = [];
const people = Array.from({ length: n }, (_, i) => i + 1);
let caseNum = people.reduce((ac, v) => ac * v, 1)
while (answer.length < n) {
caseNum = caseNum / people.length;
answer.push(...people.splice(Math.floor((k - 1) / caseNum), 1));
k = k % caseNum;
}
return answer;
}
- people = [1, 2, 3], caseNum = 3! = 6
- 첫 번째 숫자 선택:
- caseNum = 6 / 3 = 2
- (k - 1) / caseNum = (5 - 1) / 2 = 2
- people.splice(2, 1) → 3
- answer = [3]
- k = 5 % 2 = 1
- 두 번째 숫자 선택:
- caseNum = 2 / 2 = 1
- (k - 1) / caseNum = (1 - 1) / 1 = 0
- people.splice(0, 1) → 1
- answer = [3, 1]
- k = 1 % 1 = 0
- 마지막 숫자 선택:
- 남은 숫자는 [2], 그대로 answer에 추가
- answer = [3, 1, 2]
최종 결과: [3, 1, 2]
정리
- n!을 계산해서 각 자리에서 몇 번째 숫자를 고를지 정함.
- (k-1) / caseNum을 계산해서 people 배열에서 선택할 숫자의 인덱스를 구함.
- 선택한 숫자를 answer 배열에 추가하고, k 값을 갱신.
- 모든 숫자를 선택할 때까지 반복.
1. n!을 이용한 그룹 크기 계산
n!은 n개의 숫자로 만들 수 있는 모든 순열의 개수를 의미해.
각 숫자가 맨 앞에 올 때마다 가능한 경우의 수는 (n-1)!이 돼.
예를 들어, n = 4일 때 사전순으로 가능한 모든 경우의 수를 보면:
1. [1, 2, 3, 4]
2. [1, 2, 4, 3]
3. [1, 3, 2, 4]
4. [1, 3, 4, 2]
5. [1, 4, 2, 3]
6. [1, 4, 3, 2]
----------------
7. [2, 1, 3, 4]
8. [2, 1, 4, 3]
9. [2, 3, 1, 4]
10. [2, 3, 4, 1]
11. [2, 4, 1, 3]
12. [2, 4, 3, 1]
----------------
13. [3, 1, 2, 4]
14. [3, 1, 4, 2]
15. [3, 2, 1, 4]
16. [3, 2, 4, 1]
17. [3, 4, 1, 2]
18. [3, 4, 2, 1]
----------------
19. [4, 1, 2, 3]
20. [4, 1, 3, 2]
21. [4, 2, 1, 3]
22. [4, 2, 3, 1]
23. [4, 3, 1, 2]
24. [4, 3, 2, 1]
여기서 보면,
- 1이 맨 앞에 오는 경우가 6개 (3! = 6)
- 2가 맨 앞에 오는 경우도 6개 (3! = 6)
- 3이 맨 앞에 오는 경우도 6개
- 4가 맨 앞에 오는 경우도 6개
즉, 맨 앞자리 숫자 하나를 정하면 나머지 숫자로 (n-1)!개의 조합을 만들 수 있어.
2. k를 이용해 첫 번째 숫자 찾기
우리는 k번째 순열을 찾아야 해.
각 숫자가 앞에 올 때마다 (n-1)!개의 경우가 존재하므로,
첫 번째 숫자는 (k-1) / (n-1)! 를 통해 몇 번째 그룹인지 찾을 수 있어.
예제) n = 4, k = 15
- n! = 4! = 24
- (n-1)! = 3! = 6 → 첫 번째 숫자가 고정될 때 가능한 경우의 수
k = 15이면
(15 - 1) / 6 = 14 / 6 = 2번째 그룹 (0부터 시작하는 인덱스 기준)
즉, [1, 2, 3, 4] 중에서 세 번째 숫자인 3이 첫 번째 자리에 온다는 뜻이야.
3. 첫 번째 숫자를 제외한 나머지에서 k 갱신
첫 번째 숫자를 결정하고 나면,
남은 숫자에서 다시 (n-1)!을 이용해 두 번째 숫자를 찾는 방식이야.
- 첫 번째 숫자로 3을 선택하면, 남은 숫자는 [1, 2, 4]
- k = 15에서 이전 그룹(2번째 그룹)까지 계산된 숫자 개수(= 2 * 6 = 12) 를 뺀다.
- 이제 n=3에서 k=3 번째 순열을 찾아야 하므로, 다시 (n-1)!을 이용해 두 번째 숫자를 찾음.
- (n-1)! = 2! = 2
- (3 - 1) / 2 = 1 → 남은 [1, 2, 4] 중 두 번째 숫자 2 선택
- k = 3 - (1 * 2) = 1
- 이제 n=2, 남은 숫자는 [1, 4]
- (n-1)! = 1! = 1
- (1 - 1) / 1 = 0 → 첫 번째 숫자인 1 선택
- k = 1 - (0 * 1) = 1
- 마지막 남은 숫자 [4] 선택.
결과: [3, 2, 1, 4] (15번째 순열)
728x90
반응형
'코딩 테스트 준비' 카테고리의 다른 글
[프로그래머스] 리코쳇 로봇 Lv2 (0) | 2025.02.18 |
---|---|
[프로그래머스] 무인도 여행 Lv2 (0) | 2025.02.17 |
[프로그래머스] 미로 탈출 Lv2 (0) | 2025.02.14 |
[프로그래머스] 숫자 카드 나누기 Lv2 (0) | 2025.02.13 |
[프로그래머스] 시소 짝꿍 Lv1 (0) | 2025.02.12 |