코틀린 코딩테스트 강좌, 시간 복잡도 표기법 알아보기

코딩 테스팅에서 문제를 해결하는 것은 단순히 올바른 답안을 제시하는 것을 넘어, 그 답안을 얼마나 효율적으로 계산할 수 있는지를 이해하는 것이 중요합니다. 시간 복잡도는 알고리즘의 성능을 분석하는 데 핵심적인 요소입니다. 이번 포스팅에서는 코틀린을 활용하여 실제 알고리즘 문제를 풀고, 이 문제의 시간 복잡도를 분석해 보겠습니다.

문제: 두 개의 정수 배열에서 두 번째 큰 수 찾기

다음은 우리에게 주어진 문제입니다:

문제 설명: 두 개의 정수 배열이 주어졌을 때, 이 두 배열의 요소들 중 두 번째로 큰 수를 찾아 반환하시오. 두 배열은 모두 동일한 크기를 가지고 있으며, 모든 요소는 서로 다릅니다.

입력

  • 첫 번째 배열: [3, 1, 4, 5, 9]
  • 두 번째 배열: [2, 6, 5, 3, 7]

출력

두 개의 배열에서 두 번째로 큰 수: 7

접근 방법

이 문제를 해결하기 위해서는 두 배열의 모든 요소를 합쳐서 정렬한 다음, 두 번째로 큰 수를 찾아야 합니다. 하지만 단순히 정렬하는 방식은 시간 복잡도가 O(n log n)으로 높아질 수 있습니다. 따라서, O(n) 시간 복잡도로 해결할 수 있는 방법을 고민해봐야 합니다.

알고리즘 설계

1. 두 배열을 하나의 리스트로 합쳐준다.

2. 리스트에서 최대값과 최대값과 동일하지 않은 가장 큰 값을 찾아 두 번째로 큰 수를 결정한다.

이 접근법은 리스트를 한 번 돌면서 최대값을 찾고, 그 다음에 두 번째 최대값을 찾기 때문에 시간 복잡도는 O(n)입니다.

코드 구현


fun findSecondLargest(array1: IntArray, array2: IntArray): Int? {
    val combinedArray = array1 + array2
    var max = Int.MIN_VALUE
    var secondMax = Int.MIN_VALUE

    for (number in combinedArray) {
        if (number > max) {
            secondMax = max
            max = number
        } else if (number > secondMax && number != max) {
            secondMax = number
        }
    }
    return if (secondMax != Int.MIN_VALUE) secondMax else null
}

// 사용 예시
fun main() {
    val array1 = intArrayOf(3, 1, 4, 5, 9)
    val array2 = intArrayOf(2, 6, 5, 3, 7)

    val result = findSecondLargest(array1, array2)
    println("두 번째로 큰 수: $result")
}

시간 복잡도 분석

위 코드는 두 배열을 합쳐서 새로운 배열을 만들고, 이를 한 번 순회하면서 최대값과 두 번째 최대값을 찾습니다. 따라서, 전체 시간 복잡도는 다음과 같이 계산됩니다:

  • 배열 합치기: O(n)
  • 최대값 찾기: O(n)

그러므로 전체 시간 복잡도는 O(n)입니다.

결론

이번 포스팅에서는 코틀린을 활용하여 알고리즘 문제를 해결하는 방법과, 시간 복잡도를 효율적으로 분석하는 방법에 대해 알아보았습니다. 알고리즘을 설계할 때는 최적의 성능을 고려하는 것이 중요하며, 이러한 접근 방식을 익히면 더 복잡한 문제를 해결하는 데도 유용합니다.

앞으로도 다양한 코틀린 코딩테스트 문제를 해결하며 알고리즘의 깊이를 더해가길 바랍니다.