줄 서는 방법(Java)

bearMin·2024년 3월 17일

🎯문제

n명의 사람이 일렬로 줄을 서고 있습니다. n명의 사람들에게는 각각 1번부터 n번까지 번호가 매겨져 있습니다. n명이 사람을 줄을 서는 방법은 여러가지 방법이 있습니다. 예를 들어서 3명의 사람이 있다면 다음과 같이 6개의 방법이 있습니다.

  • [1, 2, 3]
  • [1, 3, 2]
  • [2, 1, 3]
  • [2, 3, 1]
  • [3, 1, 2]
  • [3, 2, 1]

사람의 수 n과, 자연수 k가 주어질 때, 사람을 나열 하는 방법을 사전 순으로 나열 했을 때, k번째 방법을 return하는 solution 함수를 완성해주세요.

제한사항

  • n은 20이하의 자연수 입니다.
  • k는 n! 이하의 자연수 입니다.

입출력 예

nkresult
35[3,1,2]

입출력 예시 설명
입출력 예 #1
문제의 예시와 같습니다.


✏️풀이

코드

import java.util.*;

class Solution {
    public int[] solution(int n, long k) {
        int[] answer = new int[n];
        List<Integer> num = new ArrayList<>();
        
        // 팩토리얼
        long f = 1;
        // 배열에 값을 저장하고 팩토리얼 계산
        for(int i = 1; i <= n; i++) {
            num.add(i);
            f *= i;
        }
        
        k--;
        int index = 0;
        // index가 n보다 작을 때까지 반복
        while(index < n) {
        	// 팩토리얼에서 n - index를 나눠줌
            f /= n - index;
            // 해당 index에 값을 num의 값을 넣어줌
            answer[index++] = num.remove((int) (k / f));
            // 위치 조정
            k %= f;
        }
        
        return answer;
    }
}

설명

규칙을 찾아서 진행하였다.

규칙을 찾아서 규칙에 맞게 계산을 한 뒤에 원하는 값을 출력하면 되는 방식이다.

num의 배열에 값을 저장하고 팩토리얼을 구해준다. 팩토리얼이란 3!에서 ! 기호를 뜻하며 3! = 3 2 1을 뜻한다. 따라서 for문을 사용해서 1부터 n까지 곱해주는 n!을 계산할 수 있고 각 숫자를 num 배열에 저장해준다.

k--를 하는 이유는 k번째 순서를 반환하는 것인데, 인덱스는 0부터 시작하기 때문에 기존의 값을 하나 감소해주는 것이다.

index는 answer 배열의 인덱스를 뜻하며 while문에서 index < n은 index가 n보다 크거나 같을 경우 answer 배열에 값을 넣을 수 없기 때문이다.

반복문을 진행해서 찾은 규칙을 계산한 뒤에 값을 넣어주면 된다.

예를 들어 n = 3, k = 5라고 할 때,

012
1 2 32 1 33 1 2
1 3 22 3 13 2 1

전체 개수 / 요소 개수 = 6 / 3 = 2
여기서 나온 2는 단위가 된다.

구할 번호 / 2 = 5 / 2 = 2.xx
여기서 나온 2는 list 배열에서 가져올 인덱스가 된다.

즉, list.remove(2) = 3이 맨 첫번째 자리가 된다.
또한 요소 1개를 구했으니 구할 번호는 단위만큼 제외를 시켜준다.
따라서 k = 5 % 2 = 1가 된다.

01
1 22 1

전체 개수 / 요소 개수 = 2 / 2 = 1
여기서 나온 1은 단위가 된다.

구할 번호 / 단위 = 1 / 2 = 0
여기서 나온 0은 list 배열에서 가져올 인덱스가 된다.

즉, list.remove(0) = 1이 두번째 자리가 된다.
또한 요소를 1개 더 구했으니 구할 번호는 단위만큼 또 제외를 시켜준다.
따라서 k = 1 % 1 = 0이 된다.

이렇게 하면 list에는 2만 남게 되고 2까지 answer 배열에 값을 넣어주면 [3, 1, 2] 라는 값이 들어가게 되고, 이를 반환하면 문제를 해결할 수 있다!


💡느낀 점

아마 이 문제를 푼 대부분이 그랬듯이 완전탐색으로 쉽게 풀 수 있을 줄 알았다. 그러나 시간초과가 나왔고 규칙을 찾으려고 하였으나, 쉽게 찾을 수 없어서 다른 풀이들을 참고해서 겨우 풀 수 있었다. 문제의 풀이를 보면서 신기하다는 생각이 제일 먼저 들었던 것 같다. 이런 비슷한 문제가 나오면 적용할 수 있도록 조금 더 코드를 살펴봐야할 것 같다..


링크

문제 링크

profile
소소한 공부기록

0개의 댓글