이 글은 인프런 [자바(Java) 알고리즘 문제풀이 : 코딩테스트 대비 ] 강의를 수강하며 작성한 글입니다.
자바(Java) 알고리즘 문제풀이 : 코딩테스트 대비 - 인프런 | 강의
자바(Java)로 코딩테스트를 준비하시는 분을 위한 강좌입니다. 코딩테스트에서 가장 많이 출제되는 Top 10 Topic을 다루고 있습니다. 주제와 연동하여 기초문제부터 중급문제까지 단계적으로 구성
www.inflearn.com
먼저 재귀함수의 원리가 이해되지 않는다면 전 게시물을 참조해주세요
2021.12.10 - [알고리즘/자바 알고리즘 문제풀이: 코딩테스트 대비] - [알고리즘/java] 재귀함수
[알고리즘/java] 재귀함수
이 글은 인프런 [자바(Java) 알고리즘 문제풀이 : 코딩테스트 대비 ] 강의를 수강하며 작성한 글입니다. - https://inf.run/Azjw 자바(Java) 알고리즘 문제풀이 : 코딩테스트 대비 - 인프런 | 강의 자바(Java)
bumbleb22.tistory.com
문제 :
피보나치 수열을 출력한다. 피보나치 수열은 앞의 2개의 수를 합한 것이 다음 숫자가 되는 수열이다.
ex) 1 1 2 3 5 8 13 21 34 55 89..
입력은 피보나치 수열의 총 항의 수이다.
피보나치 수열의 점화식은 아래와 같다.
F(0) = 0
F(1) = 1
F(n) = F(n-2) + F(n-1) (n>1, n은 정수)
-- 코드는 입력 n값을 10으로 가정하고 설명
< 재귀를 이용한 기본 피보나치 수열 >
public class Main {
public static int DFS(int n) {
if (n == 1)
return 1;
else if (n == 2)
return 1;
else {
return DFS(n - 2) + DFS(n - 1);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int n = 10;
for (int i = 1; i <= n; i++) {
System.out.print(DFS(i) + " ");
}
}
}
위와 같은 방법으로 피보나치 수열을 구할 수 있지만 n이 커질 수록 속도가 현저히 느려진다.
왜냐하면 예를 들어 1~10까지의 수열을 구한다면, 9까지의 수열을 각각 재귀를 사용해 구하고, 10번째 수열 값 또한 재귀로 구해야 하기 때문이다.
즉, DFS(10)자체가 1~10까지의 이미 수열을 구하는 과정인데 모든 수열값을 각각 재귀로 구함으로써 시간이 많이 소요된다.
< 위의 방법에서 조금 더 개선시킨 피보나치 수열 >
public class Main {
static int[] fibo;
public static int DFS(int n) {
if (n == 1)
return fibo[n] = 1;
else if (n == 2)
return fibo[n] = 1;
else {
return fibo[n] = DFS(n - 2) + DFS(n - 1);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int n = 10;
fibo = new int[n + 1];
DFS(n);
for (int i = 1; i <= n; i++) {
System.out.print(fibo[i] + " ");
}
}
}
: int형 배열 fibo에 각 리턴값을 저장하여 (수열의 값), 그 fibo배열 값을 반복문을 이용해 출력하는 방법.
<위의 방법을 메모이제이션(Memoization)을 통해 더 개선시킨 방법>
public class Main {
static int[] fibo;
public static int DFS(int n) {
if (fibo[n] > 0) //값을 구해놨다면
return fibo[n];
if (n == 1)
return fibo[n] = 1;
else if (n == 2)
return fibo[n] = 1;
else {
return fibo[n] = DFS(n - 2) + DFS(n - 1);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int n = 10;
fibo = new int[n + 1];
DFS(n);
for (int i = 1; i <= n; i++) {
System.out.print(fibo[i] + " ");
}
}
}
: 재귀를 통해 fibo배열에 저장된 return값은 또 다시 재귀호출을 통해 구하지 않도록 한다.
밑의 그림 10은 DFS(10)을 의미한다고 생각한다. (D(9), D(8), D(7) ..)
즉 그림의 회색 DFS값은 재귀를 통해 구해진 fibo값으로 리턴되는 것이다.
결론적으로 피보나치 수열을 구하는 방법은
1. 재귀
2. 배열 for문
이 두 가지 방법이 있지만 재귀는 스택프레임을 사용하기 때문에 메모리도 많이 쓰고 더 무겁다.
그래서 성능은 main에서 for문만 도는 배열이 훨씬 좋다.
'알고리즘 > 자바 알고리즘 문제풀이: 코딩테스트 대비' 카테고리의 다른 글
[알고리즘/java] 송아지 찾기 1(BFS) (0) | 2021.12.15 |
---|---|
[알고리즘/java] 이진트리 레벨탐색(BFS) (0) | 2021.12.14 |
[알고리즘/java] 부분집합 구하기(DFS) (0) | 2021.12.11 |
[알고리즘/java] 이진트리순회(DFS) (0) | 2021.12.11 |
[알고리즘/java] 재귀함수 (0) | 2021.12.10 |