다음 순열 함수(nextPermutation)을 구현해서 초기 배열에서 k번 실행하면 될 것 이라고 생각하고 해봤지만 시간초과가 나왔다. 최악의 경우 20!번의 함수 호출을 해야하기 때문이다.
그래서 특정 순열을 바로 구하는 방법을 생각해봤다. 예시로 주어진 [1, 2, 3]을 통해 손으로 쓰면서 규칙을 찾아보았다.
3명의 사람이 있을 때 5번째 순열을 구해보자.
따라서 규칙은 다음과 같다.
이 때 자릿수에 넣을 숫자는 사용하지 않은 가장 작은 수 부터 살펴봐야하므로 시작 전 숫자를 넣어둔 리스트를 오름차순 정렬한다.
import java.util.*;
class Solution {
public int[] solution(int n, long k) {
ArrayList<Integer> list = new ArrayList<>();
for(int i = 1 ; i <= n ; ++i) list.add(i);
return go(0, 0, n, k, new int[n], list);
}
private int[] go(long cnt, int idx, int n, long k, int[] answer, ArrayList<Integer> list){
if(idx == n){
return answer;
}
int num = 0;
long add = fectorial(n - (idx + 1));
Collections.sort(list);
while(true){
num = list.remove(0);
if(cnt + add >= k) break;
cnt += add;
list.add(num);
}
answer[idx] = num;
return go(cnt, idx + 1, n, k, answer, list);
}
private long fectorial(int n){
long result = 1;
while(n >= 1) result *= n--;
return result;
}
}