스위프트 코딩테스트 강좌, 줄 세우기

안녕하세요! 오늘은 스위프트 코딩테스트 강좌의 일환으로 줄 세우기 문제를 다루어 보겠습니다.
이는 코딩 면접에서 자주 나오는 문제 중 하나이며, 실제 현업에서도 많이 활용되는 알고리즘입니다.
이번 글에서는 문제의 정의, 해결 방법 및 이를 위한 스위프트 코드 예제, 그리고 최적화 전략에 대해
상세히 설명하도록 하겠습니다.

문제 정의

여러 명의 학생이 줄을 서 있습니다. 각 학생의 번호가 주어졌을 때,
학생들이 올바른 순서로 나열될 수 있도록 몇 번의 교환을 해야 하는지 계산하는 문제입니다.
학생들은 각자 자신이 몇 번째에 서야 하는지를 알고 있으며, 각 학생의
번호는 1부터 N까지의 자연수로 주어집니다. 한 번에 두 학생만 위치를 바꿀 수 있으며,
교환의 횟수를 최소로 하여 문제를 해결해야 합니다.

입력 형식

첫 번째 줄에 학생의 수 N이 주어지고, 다음 줄에 N개의 정수가 공백으로 구분되어
학생들의 현재 줄 서 있는 위치를 나타냅니다.

예제 입력

5
2 1 5 3 4
    

출력 형식

올바른 순서로 정렬하기 위해 필요한 최소 교환 횟수를 출력합니다.

예제 출력

3
    

문제 풀이 과정

이 문제를 해결하기 위해서는 위치 변경을 최소화하는 방법을 찾아야 합니다.
각 학생들이 나와야 할 순서에서 그들이 현재 위치에 있는 경우를 확인하면서,
교환이 필요한 위치를 찾는 것이 중요합니다.
기본적인 접근 방식은 “사이클 검사”를 활용하는 것입니다.
각각의 학생을 추적하면서, 그들이 올바른 위치에 들어가게 하는 과정을 추적합니다.

1단계: 사이클 분석

처음에 모든 학생의 번호를 이용하여 그들이의 올바른 위치를 계산합니다.
예를 들어, 1번 학생은 인덱스 0(i=0) 자리에 있어야 합니다.
2번 학생은 인덱스 1(j=1) 자리에 있어야 하고, 5번 학생은 인덱스 4(k=4) 자리에 있어야 합니다.
우리는 주어진 순서를 체크하여 이와 같은 올바른 위치로 이동시키기 위해서
어떤 방향으로 교환해야 할지를 체크합니다.

2단계: 교환 횟수 계산

각 학생이 올바른 자리에 서 있기 위해서는 사이클의 길이를 검사하여,
사이클의 길이를 k라고 한다면 (k-1)번의 교환이 필요합니다.
예를 들어, 사이클의 길이가 3이면 2번의 교환이 필요합니다.
따라서 전체 학생 수에서 각 사이클의 교환 수를 합산하면 최소 교환 횟수를 구할 수 있습니다.

3단계: 스위프트 코드 구현

이제 위에서 설명한 알고리즘에 따라 스위프트 코드를 작성해 보도록 하겠습니다.


    func minimumSwaps(arr: [Int]) -> Int {
        let n = arr.count
        var arrIndex = Array(0.. 0 {
                swaps += (cycle_size - 1)
            }
        }
        
        return swaps
    }
    

예제 실행

위의 함수를 사용하여 예제를 실행해 보겠습니다:


    let studentPositions = [2, 1, 5, 3, 4]
    let result = minimumSwaps(arr: studentPositions)
    print("최소 교환 횟수: \(result)")
    

코드 설명

minimumSwaps 함수는 입력으로 학생들의 현재 위치 배열을 받습니다.
– 첫 번째로, 학생들의 인덱스를 붙여 준다음 각 학생의 올바른 위치에 따라 정렬합니다.
– 방문 체크를 위한 배열을 선언하고, 각 학생의 위치에서 사이클을 검사하며
– 주어진 학생이 올바른 위치에 있지 않은 경우 사이클의 크기를 카운트합니다.
– 최종적으로, 각 사이클에 대해 (사이클 크기 – 1)만큼 교환해야 함을
– 카운트하여 반환합니다.

최적화 및 추가 고려사항

이 알고리즘은 O(N log N)으로 정렬 과정에서 큰 성능 저하가 발생할 수 있습니다.
그러나 학생의 수가 크지 않을 경우 이 접근 방식은 충분히 빠르며 효율적입니다.
이 문제를 해결하기 위해 다른 방법들도 고려할 수 있지만,
복잡도가 낮고 명확한 사이클 기반 분석이 가장 직관적이고 간단한 방법입니다.

마무리

오늘은 스위프트를 이용한 줄 세우기 문제를 통해,
알고리즘 문제 해결 능력을 향상시킬 수 있는 기회를 가졌습니다.
코드는 간단하지만, 이해하기에는 여러 개념들이 결합되어 있어
특히 사이클을 판단하는 과정이 이상적입니다.
더 많은 알고리즘과 문제 풀이를 통해 실력을 쌓고
면접 준비에 도움이 되길 바랍니다!