피보나치 수열을 구현하는데 두가지정도의 알고리즘이 대표적으로 존재한다.
반복문 + 배열로 구현
먼저, 대표적으로 배열 + 반복문으로 구현하는 방법은 아래와 같다.
package Array;
import java.util.*;
public class Fibonacci {
public static int[] fib(int n) {
int[] arr = new int[n];
for (int i = 0; i < arr.length; i++) {
if (i == 0 || i == 1) {
arr[i] = 1;
} else {
arr[i] = arr[i - 2] + arr[i - 1];
}
}
return arr;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] answer = fib(n);
for (int i : answer) {
System.out.print(i + " ");
}
}
}
배열의 인덱스가 0이나 1일 때는 원소의 값을 1로 집어 넣는 복잡도가 O(1)이고, 인덱스가 0 또는 1이 아닐 때 원소값을 삽입하는 복잡도는 대략 O(n) 정도이다. 즉 배열과 반복문으로 풀면 복잡도는 O(n) 정도이다.
DFS 로 구현
기본적으로 DFS는 메서드를 재귀적으로 호출한다. 구현은 아래와 같다.(편의상 마지막 값만 출력)
import java.util.*;
public class DFSFibonacci {
public static int fib(int n) {
if (n == 1) {
return 1;
} else if (n == 2) {
return 1;
} else {
return fib(n - 2) + fib(n - 1);
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
System.out.println(fib(n));
}
}
로직은 배열로 작성했을때와 같다. 다만 값이 0또는 1이 아닐때는 메서드를 재귀적으로 호출하여 값을 구하는 점에서 차이점이 존재한다.
시간복잡도를 계산해보자.
fib(n) 메서드는 반복적으로 fib(n-1) 와 fib(n-2)를 호출한다. -> 즉 메서드를 호출할수록 호출이 분기를 생성해낸다.
이를 재귀적으로 분기한다고 하는데, 위 예제에서는 대략 2^n에 비례한다. -> 즉 복잡도는 O(2^n) 에 비례한다.
현재처럼 간단한 코드에서는 일단 배열 + 반복문 조합으로 푼 방식이 더 효율적이다.
다만 DFS을 최적화 하는 방법중에 메모이제이션이라는 방법이 있는데, 이는 추후에 써보겠다!
오늘은 그냥 간단한 구현이 목적이었다.
'Algorithm > CT' 카테고리의 다른 글
[Algorithm] 팰린드롬 수 - (백준 1259) (1) | 2024.12.26 |
---|---|
[Algorithm] 올바른 괄호 (Java) - Stack 보단 Deque (0) | 2024.12.24 |
[Java] [이코테] 1이 될 때까지 (0) | 2024.09.19 |
[Java] [프로그래머스] 햄버거 만들기 (0) | 2024.09.12 |
[Algorithm] [백준] 항상 문제를 잘 읽어라(11382번) (0) | 2024.07.27 |