알고리즘 문제를 풀거나 알고리즘 문제를 풀다가 막혀서 다른 사람의 풀이를 볼 때 자주 들리는 단어들이 있을 것이다 그 중 우리는 오늘은 알고리즘 문제 풀이에서 중요한 개념인 ‘빅오 표현법’과 ‘시간 복잡도’에 대해 설명하려고 한다
빅오 표현법(Big O Notation)이란?
우선 빅오 표현법에 대해 먼저 알아보면 빅오 표현법이란 알고리즘의 효율성을 표현하는 방법 중 하나로 주로 알고리즘의 ‘최악의 경우’에 대한 실행 시간이나 필요한 메모리 공간을 나타내는 데 사용되는 표현법이다
기본적인 빅오 표현들을 살펴보면
O(1) - 상수 시간: 입력 크기에 상관없이 일정한 시간이 걸리는 알고리즘이다 ex) 배열의 특정 요소에 접근하기
O(N) - 선형 시간: 알고리즘 실행 시간이 입력 크기에 비례해서 증가하는 알고리즘이다 ex) 배열의 모든 요소를 한 번씩 확인하기
O(N²) - 제곱 시간: 주로 이중 루프에서 발생한다 ex) 2차원 배열의 모든 요소를 확인하기
O(log N) - 로그 시간: ex) 이진 탐색
이렇게 확인할 수 있다
시간 복잡도(Time Complexity)란?
다음으로 보통 빅오 표현법과 묶여서 설명되는 시간 복잡도에 대해서도 알아보면 시간 복잡도는 알고리즘이 문제를 해결하는데 걸리는 시간을 추정할 수 있는 방법으로 시간 복잡도를 통해 입력 크기가 커질 때 알고리즘의 실행 시간이 어떻게 변하는지 파악할 수 있어서
알고리즘 문제를 풀 때 시간 복잡도를 계산하여 시간 초과가 발생하는지 테스트 케이스를 거치지 않고도 미리 계산할 수 있기에 잘못된 알고리즘을 제출하거나 잘못된 알고리즘을 구현하느라 시간 낭비하는 일을 막을 수 있다
시간 복잡도 계산하기
그렇다면 이러한 시간 복잡도는 어떻게 계산할 수 있을까? 시간 복잡도를 계산하는 방법은 생각보다 어렵지 않은데
알고리즘을 구성하는 기본 단위의 연산 즉 가장 많이 반복되는 연산을 파악한다
이 연산이 얼마나 자주 발생하는지 계산한다
최고차항만 남기기 예를 들면 3N² + 2N + 1에서는 3N²만 남긴다
마지막으로 계수를 생략하여 위와 같은 경우에는 최종적으로 O(N²) 같은 형태로 표현한다
실제 예시로 이해하기
이제 마지막으로 실제 예시를 통해 시간 복잡도를 구해보면
1
2
3
4
5
def sum_array(arr):
total = 0
for element in arr:
total += element
return total
위 코드는 배열 내의 모든 요소의 합을 구하는 알고리즘으로 해당 알고리즘에서는 배열의 각 요소를 한 번씩만 확인하므로 시간 복잡도는 O(N)이다
결론
이렇게 빅오 표현법과 시간 복잡도에 대해서 알아봤는데 마지막으로 추가적인 팁을 주자면 대충 프로그래밍에서 1억번 연산이 1초이기 때문에 이를 이용하여 시간 제한을 구하면 편하다
밑은 1초까지 몇번 가능한지 나타낸 표이다
- O(1) : 1억
- O(logN) : 1억
- O(N) : 1억
- O(nLogN): 5백만
- O(N^2) : 1만
- O(N^3) : 500
- O(2^N) : 20
- O(N!): 10