본문 바로가기
코딩 테스트 수련의방/알고리즘

순열

by L3m0n S0ju 2023. 10. 7.

 

 

 

 

 

오늘 LG CNS 코딩테스트를 쳤다. 3문제 중에 2문제는 테스트 케이스를 통과했고 1문제는 풀지 못했다.

아마도 문제가 전부 쉬워서 떨어질 것 같긴하다.

2번째 문제를 푸는데 dfs로 잘 안풀려서 고민하다가 마지막 20분 전에 순열로 풀 수 있는 방법이 떠올라서 열심히 했는데 시간 내에 완성하지 못하고 그냥 제출했다. 

 

순열은 그냥 dfs나 브루트포스처럼 전부 계산하면 되긴 하지만 시간 제한 때문에 조금 알고리즘을 알아두면 좋을 것 같다.

밑에 다음 순열을 구하는 알고리즘은 오늘 시험과는 무관하지만 그냥 순열을 공부하다보니 자주 등장하길래 한번 정리해봤다.

 

 

 

백준 - 다음 순열

 

int i = 배열 마지막 인덱스,

int j = 배열 마지막 인덱스 일때

1. i > 0 이면서 A[i] > A[i-1]를 만족하는 카장 큰 i를 찾는다.

2. A[j] > A[i-1]을 만족하는 가장 큰 j를 찾는다.

3. A[i-1]과 A[j]를 swap한다.

4. A[i]부터 순열을 뒤집는다.

 

뭔가 직관적인 알고리즘은 아닌 것 같다. 고등학교 때 배운적이 없어서 그런지 처음에는 간단해보이지만 생각하는데 조금 시간이 들었다.

 

 

예를 들어 

 

1 5 2 4 3 을 입력을 넣으면 (1), (2) 과정을 거치면서

 

i는 3이고 j는 4이 된다.

 

(3) 과정을 거치면 1 5 3 4 2 가 된다.

 

마지막으로 (4) 과정을 거치면 1 5 3 2 4 가 된다.

 

숫자 5개로 하면 뭔가 직관적이지 않다.

 

 

조금 더 쉬운 이해를 위해 더 큰 입력을 넣는다. 

7 1 5 6 4 3 2

 

i, j는 각각 3, 3이 된다.

 

(3)과정을 거치면 7 1 6 5 4 3 2 가 된다.

(4) 과정을 거리면 7 1 6 5 4 3 2이 된다.

 

계속 시도하다 보면 규칙이 보인다.

 

 

 

 

 


백준 - 다음 순열

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    static int n;

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        n = Integer.parseInt(st.nextToken());
        int[] arr = new int[n];
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < n; i++) {
            arr[i] = Integer.parseInt(st.nextToken());
        }
        int i = n - 1;
        int j = n - 1;
        // 과정 (1)
        while (i > 0 && arr[i - 1] >= arr[i]) {
            i--;
        }
        if(i == 0) {
            System.out.print(-1);
            return;
        }
        
        // 과정 (2)
        while (arr[i - 1] >= arr[j]) {
            j--;
        }
        
        // 과정 (3)
        swap(arr, i - 1, j);

        // 과정 (4)
        int j = n - 1;
        while (i < j) {
            swap(arr, i, j);
            i += 1;
            j -= 1;
        }

        for (int l = 0; l < n; l++) {
            System.out.print(arr[l] + " ");
        }
    }

    public static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}

'코딩 테스트 수련의방 > 알고리즘' 카테고리의 다른 글

정렬 알고리즘 시간 복잡도  (0) 2023.12.10
LIS 알고리즘  (0) 2023.08.09
크루스칼 알고리즘  (0) 2023.06.18
다익스트라 알고리즘  (0) 2023.06.18
투 포인터 알고리즘  (0) 2023.06.17

댓글