코틀린 코딩테스트 강좌, 시간 복잡도 활용하기

안녕하세요! 오늘은 코틀린을 활용한 코딩 테스트 준비를 위한 강좌를 진행하겠습니다. 이번 강좌의 주요 주제는 ‘시간 복잡도’입니다. 코딩 문제를 풀 때 시간 복잡도를 어떻게 분석하고 최적화할 수 있는지에 대해 알아보겠습니다. 또한, 실제 문제를 하나 풀어보며 시간 복잡도를 계산해 보겠습니다.

문제 설명

주어진 정수 배열 nums에서의 두 개의 수가 합이 특정 값 target이 되는 경우를 찾아서 해당 수의 인덱스를 반환하는 문제를 다루겠습니다.

문제: 정수 배열 nums와 정수 target이 주어졌을 때, nums[i] + nums[j] = target를 만족하는 인덱스 ij를 반환하라. 각 입력에 대해 한 번의 출력만 가능하며, 같은 요소를 두 번 사용해서는 안 된다.

입력 예시

nums = [2, 7, 11, 15], target = 9

출력 예시

[0, 1]

문제 풀이 과정

이 문제를 해결하기 위해 먼저 알고리즘을 설계해 보겠습니다. 흔히 사용하는 해결 방법으로는 폭 brute-force 방식, 해시맵을 이용한 방식이 있습니다.

1. Brute-force 방식

가장 간단한 방법은 두 개의 중첩된 반복문을 사용하여 모든 가능한 조합을 확인하는 것입니다. 이 경우 시간 복잡도는 O(n^2)가 됩니다.


    fun twoSum(nums: IntArray, target: Int): IntArray {
        for (i in nums.indices) {
            for (j in i + 1 until nums.size) {
                if (nums[i] + nums[j] == target) {
                    return intArrayOf(i, j)
                }
            }
        }
        throw IllegalArgumentException("No two sum solution")
    }
    

2. 해시맵을 이용한 최적화

해시맵을 사용하면 1회 반복으로 해결할 수 있습니다. 이 방법의 기본 아이디어는 각 요소를 반복하면서 필요한 값(target – 현재 값)이 이미 해시맵에 존재하는지 확인하는 것입니다. 이 경우 시간 복잡도는 O(n)으로 줄어듭니다.


    fun twoSum(nums: IntArray, target: Int): IntArray {
        val map = mutableMapOf()
        for (i in nums.indices) {
            val complement = target - nums[i]
            if (map.containsKey(complement)) {
                return intArrayOf(map[complement]!!, i)
            }
            map[nums[i]] = i
        }
        throw IllegalArgumentException("No two sum solution")
    }
    

시간 복잡도 분석

brute-force 방식의 시간 복잡도는 중첩된 두 반복문으로 인해 O(n^2)이며, 해시맵을 이용한 방식은 하나의 반복문만 사용하므로 O(n)의 시간 복잡도를 갖습니다. 따라서 해시맵을 이용한 접근이 메모리 사용량이 더 커질 수 있지만, 실행 속도 면에서는 훨씬 유리합니다.

결론

이번 강좌에서는 코틀린을 활용하여 두 수의 합 문제를 해결하는 과정을 살펴보았고, 각 접근 방법의 시간 복잡도를 어떻게 분석하고 최적화할 수 있는지를 학습하였습니다. 이처럼 시간 복잡도 분석은 효율적인 알고리즘 설계에서 매우 중요한 요소임을 기억해 주세요. 앞으로 코딩 테스트를 준비하면서 다양한 문제를 풀고, 이 과정에서 시간 복잡도 능력을 키우는 것이 중요합니다.

참고 자료

이상으로 이번 강좌를 마치겠습니다. 다음 시간에도 더 재미있고 유익한 주제로 찾아오겠습니다. 감사합니다!