[알고리즘]Space and Time Complexity (시간 복잡도, 공간 복잡도)

Date:     Updated:

카테고리:

복잡도(Complexity)란?

  • 알고리즘의 성능, 효율성을 나타내는 척도.
  • Ex) 시간 복잡도(Time Complexity), 공간 복잡도(Space Complexity).
  • 시간 복잡도는 한 입력에 대해서 최악의 케이스(worst case)에 대한 알고리즘의 수행 시간을 나타냄.
  • 공간 복잡도는 한 입력에 대해서 알고리즘을 수행하며 사용하는 메모리의 최대량을 나타냄.
  • 점근 표기법에는 \(O\)(빅오), \(\Theta\)(세타), \(\Omega\)(오메가) 등이 있으며 빅오와 세타를 가장 많이 사용함.

이 때, 시간 복잡도와 공간 복잡도에서 중요한 개념이 한 가지 등장한다. 복잡도를 사용하는 이유는 정확한 수행 시간, 혹은 정확한 메모리 사용량을 비교하려는 것이 아니다. 복잡도는 직관적으로 알고리즘의 성능을 분석하기 위한 도구이다. 예를 들어, 두 알고리즘의 입력이 \(n\)개이고, 각각 1번의 연산과 2번의 연산을 한다고 가정하자. 그러면 두 알고리즘의 시간 복잡도는 각각 \(n\)과 \(2n\)이 된다. 이 때, 시간 복잡도의 개념하에서는 \(2n\)과 \(n\)은 동일한 시간 복잡도를 가지는 것으로 본다. 이를 분할 상환 시간 복잡도(Amortized Time Complexity)라고 한다. 공간 복잡도도 마찬가지로 일반적인 상황에서는 분할 상환 공간 복잡도(Amortized Space Complexity)의 개념으로 측정하게 된다.

빅오 표기법(Big-O Notation)

개념념

빅오 표기법(Big-O notation)은 복잡도를 나타내는 점근 표기법 중 가장 많이 사용되는 표기법이다. 빅오 표기법이 가장 많이 사용되는 이유는 알고리즘 효율성을 상한선 기준으로 표기하기 때문이다.

1

  • 수학적 정의
  • \(O(g(n))\) = {\(f(n)\) : there exist positive constants \(c\) and \(n_0\) such that \(0≤f(n)≤cg(n)\) for all \(n≥ n_0\)}

즉, \(n_0\)를 기준으로 \(n_0\)보다 오른쪽에 있는 모든 \(n\)값에 대해 함수 \(f(n)\)은 함수 \(cg(n)\)보다 같거나 작다는 의미이다. 이는 다시 말해, 평가하고자 하는 알고리즘이 아무리 비효율적이더라도 빅오 표기법에서는 함수와 같거나 좋다. 따라서, 최악의 경우를 고려하는 데 가장 좋은 표기법이다 (알고리즘 효율성은 값이 클수록, 즉 그래프가 위로 향할수록 비효율적임을 의미)

시간 복잡도도 점근 표기법(Asymptotic Notation)을 사용하여 나타내며, 가장 높은 차수의 항만을 고려한다.

  • 빅오는 상한선을 기준으로 표기함.
  • 빅오메가는 하한선을 기준으로 표기함.
  • 빅세타는 상한선과 하한선 사이를 기준으로 표기함.



시간 복잡도(Time Complexity)

시간 복잡도는 Worst Case에 대한 알고리즘의 수행시간을 나타낸다. 다음의 두 함수 함수1함수2를 비교해보자.

[함수1]


def function1(x: int):
  cnt = 0
  for i in range(x):
    cnt +=1

  cnt += 1
  return cnt

[함수2]

def function2(x: int):
  cnt = 0
  for i in range(x):
    for j in range(x):
      cnt +=1

  for i in range(x):
    cnt += 1
  cnt += 1
  return cnt      

함수1은 for문을 x번 반복하고, 마지막에 cnt에 1을 더해주는 연산을 한다. 따라서 총 \(O(x + 1)\)만큼의 연산을 하게 된다. 반면 함수2는 이중으로 반복문을 돌며, 마지막에 1을 더해주는 연산을 하기 때문에 \(O(x^2 + x + 1)\)이 된다. 분할 상환 방식에 의해 두 함수의 최종 시간 복잡도는 다음과 같이 정의된다.

  • 함수1
    • 정확한 시간 복잡도: \(O(x+1)\)
    • 점근적 시간 복잡도: \(O(x)\)
  • 함수2
    • 정확한 시간 복잡도: \(O(x^2 + x + 1)\)
    • 점근적 시간 복잡도: \(O(x^2)\)

시간 복잡도는 상수함수< 로그함수 < 선형함수 < 다항함수 < 지수함수 순서로 지수함수로 갈수록 성능적으로 떨어진다.

$$O(1) < O(\log n) < O(n) < O(n \log n) < O(n^2) < O(2^n)$$

자료구조별 시간 복잡도 비교

1



공간 복잡도

개념

공간 복잡도(Space Complexity)는 알고리즘을 실행하는 동안 필요로 하는 메모리 공간의 양을 나타낸다. 이는 주로 다음 두 가지 요소로 구성된다.

  • 고정 공간(Fixed Part): 입력 크기와 무관하게 항상 일정한 공간을 차지하는 부분. (e.g., 변수 선언이나 상수 등.)
  • 가변 공간(Variable Part): 입력 크기에 따라 변하는 공간. (e.g., 동적 배열, 재귀 호출 스택 등.)

공간 복잡도도 점근 표기법(Asymptotic Notation)을 사용하여 나타내며, 시간 복잡도와 마찬가지로 가장 높은 차수의 항만을 고려한다.

[함수1]

def function1(x: int):
  cnt = 0
  return x + cnt

[함수2]

def function2(x: int):
  cnt = [0] * x
  return sum(cnt)

위의 예시를 보면, 1의 경우 출력받는 값이 상수이므로, 메모리에서도 상수 하나만을 저장하면 된다. 따라서 함수1의 공간 복잡도는 \(O(1)\)이 된다. 반면, 함수2를 보면 함수2는 길이가 x인 리스트를 반환받게 된다. 따라서 리스트의 요소 수만큼의 저장공간을 필요로 하므로 공간 복잡도는 \(O(x)\)가 된다.

Reference

[블로그]복잡도(Complexity): 시간 복잡도와 공간 복잡도, 그리고 빅오(Big-O) 표기법

Algorithm 카테고리 내 다른 글 보러가기

댓글 남기기