Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Algorithm] 시간복잡도와 공간복잡도 업데이트 #25

Merged
merged 10 commits into from
Mar 28, 2021
2 changes: 1 addition & 1 deletion contents/algorithm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## 알고리즘 기본 [▶︎ 🗒](basic.md)

- 시간복잡도와 공간복잡도
- [시간복잡도와 공간복잡도](basic.md#시간복잡도와-공간복잡도)
- 완전 탐색 알고리즘 (Brute Force)
- DFS와 BFS
- 순열, 조합, 부분집합
Expand Down
38 changes: 36 additions & 2 deletions contents/algorithm/basic.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# 알고리즘 기본

> 작성자 : [권혁진](https://github.com/KimKwon)
> 작성자 : [권혁진](https://github.com/KimKwon), [박재용](https://github.com/ggjae)

<details>
<summary>Table of Contents</summary>
Expand All @@ -17,8 +17,42 @@

---

알고리즘은 **완전탐색**(**Brute-Force**, 모든 경우의 수를 탐색해보는 것)에서 시작한다. 이는 모든 경우의 수를 다 따져보기 때문에 강력하지만, 최대의 시간복잡도를 가지게 된다. 모든 경우의 수를 생각해보고 또한 시간복잡도를 줄일 수 있는 부분이 있다면 그러한 알고리즘을 생각해보고 그 알고리즘을 정확하게 코드로 구현할 수 있어야 한다. 좋은 코드를 짜기 위해서는 다음 과정의 연습이 필요하다.

- 문제를 파악하고 알고리즘을 생각하기
- 알고리즘의 공간복잡도와 시간복잡도를 계산하여 문제의 제약 조건 내에 수행될 수 있는 알고리즘인지 판단하기
- 알고리즘을 빠르고 정확하게 구현하기 (연습만이 정답)

## 시간복잡도와 공간복잡도

복잡도는 알고리즘의 성능을 나타내는 척도이다.
복잡도는 **시간 복잡도(Time Complexity)** 와 **공간 복잡도(Space Complexity)** 로 나눌 수 있다.
시간 복잡도는 특정한 크기의 입력에 대하여 알고리즘이 얼마나 오래 걸리는지를 의미하고 공간 복잡도는 특정한 크기의 입력에 대하여 알고리즘이 얼마나 많은 메모리를 차지하는지를 의미한다.
동일한 기능을 수행하는 알고리즘이 있다면 일반적으로 복잡도가 낮을수록 좋은 알고리즘이다.
복잡도의 측정으로 우리는 '알고리즘을 위해 필요한 연산의 횟수'로 시간 복잡도를 계산할 수 있고 '알고리즘을 위해 필요한 메모리의 양'으로 공간 복잡도를 계산할 수 있다.

### 시간 복잡도

보통 시간 복잡도를 표현할 때는 [Big-O 표기법(Big-O notation)](https://ko.wikipedia.org/wiki/%EC%A0%90%EA%B7%BC_%ED%91%9C%EA%B8%B0%EB%B2%95)을 사용한다. 가장 빠르게 증가하는 항만 고려하는 표기법으로 limit을 나타낸다.
예를 들어 N개의 데이터가 있을 때 모든 데이터의 값을 더한 결과를 출력하는 프로그램이라면 N개의 데이터를 받아 차례로 N회 더해준다. 이 때 연산 횟수는 N에 비례하고 새로운 변수를 만들거나 출력하는 연산은 상대적으로 N이 커진다면 무시할 수 있게 된다. 가장 영향력이 큰 부분이 N으로 시간 복잡도를 O(N)으로 표시한다.
일반적으로 코딩테스트에서는 최악의 경우에 대한 연산 횟수가 가장 중요하므로 자신이 작성한 소스코드를 정확히 이해하고 분석하여 최악의 경우의 시간 복잡도를 계산해야 한다.
O(N<sup>3</sup>)을 넘어가면 문제 풀이에서 사용하기 어려운 알고리즘으로 N이 1000개를 넘어가면 5초 이상의 시간이 소요될 것이라고 예상할 수 있다.

- N의 범위가 500인 경우) 시간 복잡도가 O(N<sup>3</sup>)인 알고리즘을 설계하면 문제 해결 가능
- N의 범위가 2000인 경우) 시간 복잡도가 O(N<sup>2</sup>)인 알고리즘을 설계하면 문제 해결 가능
- N의 범위가 100,000인 경우) 시간 복잡도가 O(Nlog N)인 알고리즘을 설계하면 문제 해결 가능
- N의 범위가 10,000,000인 경우) 시간 복잡도가 O(N)인 알고리즘을 설계하면 문제 해결 가능

> 보통 1억(10<sup>8</sup>)번의 연산당 1초의 시간이 걸린다고 간주한다.

### 공간 복잡도

공간 복잡도를 표기할 때에도 [Big-O 표기법(Big-O notation)](https://ko.wikipedia.org/wiki/%EC%A0%90%EA%B7%BC_%ED%91%9C%EA%B8%B0%EB%B2%95)을 사용한다.
코딩 테스트에서는 보통 메모리 사용량을 128~512MB로 제한하고 있다. 즉 일반적인 경우 데이터의 개수가 1,000만 단위를 넘어가지 않도록 알고리즘 설계를 해야하고 100만 개 이상의 데이터가 들어갈 수 있는 크기의 배열을 선언하는 경우는 거의 드물다.
리스트의 크기가 1,000만 단위 이상이라면 자신이 알고리즘을 잘못 설계한 것이 아닌지 확인하는 과정이 필요하다.

일반적으로 알고리즘 문제 풀이에서의 복잡도는 시간 복잡도를 의미한다.

---

## DFS와 BFS
Expand All @@ -45,4 +79,4 @@

---

## 동적 계획법 (Dynamic Programming)
## 동적 계획법 (Dynamic Programming)