알고리즘이란?
알고리즘(Algorithm)은 문제를 해결하기 위한 단계적인 절차입니다.
꼭 프로그래밍이 아니더라도, 다양한 분야에서 사용됩니다.
- 입력(Input)을 받아
- 정해진 단계(Steps)를 거쳐
- 원하는 출력(Output)을 만드는 방법
✅ 좋은 알고리즘의 특징
- 명확성: 단계마다 애매하지 않음
- 유한성: 언젠가는 끝남
- 실행 가능성: 실제로 수행할 수 있음
- 일관성: 같은 입력이면 같은 결과
알고리즘 전투력 측정기, Big-O 표기법
Big-O 표기법은 입력 크기(n)에 따라 알고리즘이 얼마나 빠른지, 얼마나 많은 메모리를 쓰는지를 표현합니다.
특히 최악의 상황(worst-case) 기준으로 계산하므로 알고리즘의 효율성을 과장하지 않습니다.
Big-O 표기법 예시
표현 | 명칭 | 뜻 |
O(1) | 상수 시간 | 입력의 크기에 상관없이 항상 일정한 시간이 걸립니다. |
O(n) | 선형 시간 | 입력의 크기에 비례하여 시간이 걸립니다. |
O(n²) | 이차 시간 | 입력의 크기의 제곱에 비례하여 시간이 걸립니다. |
O(log n) | 로그 시간 | 입력의 크기의 로그에 비례하여 시간이 걸립니다. |
O(2ⁿ) | 지수 시간 | 입력의 크기의 지수에 비례하여 시간이 걸립니다. |
Big-O 계산 팁
상수는 무시: O(3n) → O(n)
가장 높은 차수만 남김: O(n² + n) → O(n²)
다항식은 최고 차수 중심: O(5n³ + n² + 2n) → O(n³)
시간 복잡도 (Time Complexity)
시간 복잡도란 알고리즘이 문제를 해결하는데 걸리는 시간을 나타내는 척도입니다.
실제 시간(초)이 아니라, 연산 횟수 기준으로 계산합니다.
예시 1
// O(n)
int Sum(int n)
{
int sum = 0;
for (int i = 0; i <= n; i++)
{
sum += i;
}
return sum;
}
for 반복문이 0부터 n까지 순회하며 합계를 더합니다. 따라서 n회의 연산이 필요하며, 시간 복잡도는 O(n)입니다.
예시 2
// O(n²)
void PrintPairs(int n)
{
for (int i = 0; i <= n; i++)
{
for (int j = 0; j <= n; j++)
{
Console.WriteLine(i + ", " + j);
}
}
}
두 개의 이중 중첩된 반복문을 포함하고 있습니다.
각 루프는 0부터 n까지 순회하므로, 전체 연산 횟수는 n² 이며, 시간 복잡도는 O(n²)입니다.
예시 3
// O(2^n)
int Fibonacci(int n)
{
if (n <= 1) return n;
return Fibonacci(n - 1) + Fibonacci(n - 2);
}
재귀적으로 피보나치 수열을 계산하는 함수입니다.
이 함수는 각 호출마다 두 번의 재귀 호출을 수행하므로, 시간 복잡도는 O(2^n)입니다.
이는 매우 비효율적인 방법으로
실제 문제 해결에서는 동적 프로그래밍 등의 기법을 사용해 효율성을 높이는 것이 중요합니다.
공간 복잡도 (Space Complexity)
알고리즘이 얼마나 많은 메모리를 사용하는지 나타내는 척도입니다. 입력 크기에 따라 변하는 메모리 사용량만 고려합니다.
예시 1
// O(n) 시간복잡도, O(1) 공간복잡도
int FindMax(int[] arr)
{
int max = arr[0];
for (int i = 1; i < arr.Length; i++)
{
if (arr[i] > max)
{
max = arr[i];
}
}
return max;
}
for 반복문이 있지만 추가적인 메모리 사용이 없으므로 시간 복잡도 O(n), 공간 복잡도 O(1)
예시 2
// O(n²) 시간, O(1) 공간
int FindMax2(int[] arr)
{
for (int i = 0; i < arr.Length; i++)
{
bool isMax = true;
for (int j = 0; j < arr.Length; j++)
{
if (arr[j] > arr[i])
{
isMax = false;
break;
}
}
if (isMax) return arr[i];
}
return -1;
}
for 이중 중첩 반복문이 있지만 추가적인 메모리 사용이 없으므로 시간 복잡도 O(n²), 공간 복잡도 O(1)