n명의 사람이 일렬로 줄을 서고 있습니다. n명의 사람들에게는 각각 1번부터 n번까지 번호가 매겨져 있습니다. n명이 사람을 줄을 서는 방법은 여러가지 방법이 있습니다.
사람의 수 n과, 자연수 k가 주어질 때, 사람을 나열 하는 방법을 사전 순으로 나열 했을 때, k번째 방법을 return하는 solution 함수를 만들어주세요.
예시:
n = 3, k = 5.
n = 3명이 줄 서는 경우의 수는
- [1, 2, 3]
- [1, 3, 2]
- [2, 1, 3]
- [2, 3, 1]
- [3, 1, 2]
- [3, 2, 1]
여기서 k = 5번째 경우는 [3, 1, 2].
따라서 정답은 [3, 1, 2]가 된다.
자세한 설명 -programmers.co.kr/learn/courses/30/lessons/12936
풀이
1. 무식한 방법
- 처음엔 무식하게! 그러나 간단하게 풀어보려 했다.
from itertools import permutations
def solution(n, k):
baseArr = [x for x in range(1,n+1)]
arr = list(permutations(baseArr, n))
answer = list(arr[k-1])
return answer
- 하지만 이는 효용성 테스트를 통과하지 못했다 ㅠ
- n이 20 이하로 주어지고,
- 따라서 permutations의 개수는 최악의 경우 n! = 20! = 2,432,902,008,176,640,000... 세기도 어렵다그니까...음... 사실 세지도 못하겠다! 암튼 1억은 훌쩍 넘어가는 수가 되버린다!!! (영어로는 2 quintillion 어쩌구가 된다고 한다. 이런 단어 난생 처음 들어본당!)
- 그러므로 모든 permutations의 경우의 수를 따져보는 것이 아니라, 주어진 n과 k에서 규칙을 도출해서 바로 바로 answer 배열을 채워줘야 되겠다.
2. 덜 무식한 방법
- 보니까, 규칙이 보였다.
- 만약 n = 4이라면,
처음 6개 - (n-1)! = (4-1)! = 3! = 6 - 의 경우는 1로 시작하고, 다음 6개의 경우는 2로 시작하고, ... 이런 패턴이 보인다.
처음 6개의 경우 중에서도, 처음 2개 - (n-2)! = (4-2)! = 2! = 2 - 의 경우는 1을 제외한 나머지 수들 중 처음 있던 숫자로 시작한다.
처음 6개 경우 중에, 처음 2개 경우 중에, 처음 1개 - (n-3)! = (4-3)! = 1! = 1 - 의 경우는 1, 2를 제외한 나머지 수들 중 처음 있던 숫자로 시작한다.
이런 패턴으로 봤을 때, 풀이를 다음과 같이 구성할 수 있다.
파이썬 구현
import math
def solution(n, k):
nums = [x for x in range(1,n+1)]
answer = []
while n > 0:
n -= 1
q, r = divmod(k, math.factorial(n)) # Step 1
if r == 0: # Step 2
q -= 1
curr = nums[q]
answer.append(curr) # Step 3
nums.remove(curr) # Step 4
k = r # Step 5
return answer
Step 1
- k를 (n-i)!로 나눈 몫과 나머지를 저장
Step 2
- 나머지가 0이라면 - 예를 들어 n=3, k=2일 때, 처음 루프의 경우 - 몫에서 1을 빼준다. index는 0부터 시작하기 때문
Step 3
- 남은 수들 중에 q번째 있는 수를 answer에 붙여줌
Step 4
- 방금 answer에 붙여준 수를 후보 숫자 배열에서 없애줌
Step 5
- k를 나머지로 설정하고 - "몇 번째 그룹" 안에서 또 몇 번째 위치에 있는 지를 탐색해야 하므로 - 루프 다시 돔
Step 2에서 조금 헷갈렸다.
이렇게 풀면, 가능한 모든 permutations의 경우를 배열로 만들어 줄 필요 없이, 하나의 배열만 만들어내면 되니 효용성 테스트도 넘어갈 수 있겠다.
'프로젝트들 > 코딩 테스트' 카테고리의 다른 글
[코딩테스트] 프로그래머스 - 2xn타일링 (Lv.3) in Python (0) | 2021.03.18 |
---|---|
[코딩테스트] 프로그래머스 - [1차]추석 트래픽(2018 Kakao) (Lv.3) in Python (0) | 2021.03.17 |
[코딩 테스트] 프로그래머스 - 가장 긴 팰린드롬 (Lv.3) in Python (0) | 2021.03.15 |
[코딩 테스트] 프로그래머스 - 가장 먼 노드 (0) | 2021.03.15 |
[코딩 테스트] 프로그래머스 - 단속 카메라(Lv.3) in Python (0) | 2021.03.14 |
댓글