이번 포스팅은 피보나치 수입니다.
혼자 피보나치 수를 풀어볼 때는 재귀 형식으로 문제를 풀었었습니다.
public static void main(String[] args) {
int answer = finbonachi(n);
}
public int fibonachi(n) {
if(n == 0) return 0;
else if(n == 1) return 1;
else return fibonachi(n-1) + fibonachi(n-2);
}
피보나치 수를 재귀적으로 호출하게 된다면
숫자가 크면 클수록 호출되는 양이 기하급수적으로 늘어나게 됩니다.
따라서 이번 문제를 풀 때는 동적 프로그래밍 기법을 알아야 합니다.
동적 프로그래밍이란?
: 큰 문제를 한 번에 해결하기 힘들 때 작은 여러 개의 문제로 나누어서 푸는 기법인데요. 작은 문제들을 풀다보면 같은 문제들을 반복해서 푸는 경우가 생깁니다. 그 문제들을 매번 재계산하지 않고 값을 저장해두었다가 재사용하는 기법이 동적 프로그래밍입니다.
동적 프로그래밍 구현 방법에는 두 가지가 있습니다.
(1) Top-down
Top-down은 재귀함수로 구현하는 경우가 많습니다.
위에 작성된 피보나치 코드방식이 Top-Down 방식입니다.
- fib(5)
- fib(4) + fib(3)
- (fib(3) + fib(2)) + (fib(2) + fib(1))
- ((fib(2) + fib(1)) + (fib(1) + fib(0))) + ((fib(1) + fib(0)) + fib(1))
- (((fib(1) + fib(0)) + fib(1)) + (fib(1) + fib(0))) + ((fib(1) + fib(0)) + fib(1))
와 같은 방식으로 호출하기 때문에 fib(0), fib(1) 같은 경우는 여러번 호출됩니다.
그러면 속도가 굉장히 느려지기 때문에 효율이 떨어집니다.
(2) Bottom-up
Bottom-up 방식은 작은 문제부터 차례로 구해나가는 방식입니다.
public int bottomUp(int n) {
int[] arr = new int[n];
arr[0] = 0; arr[1] = 1;
if(n == 0) return arr[0];
else if(n == 1) return arr[1];
else {
for(int i = 2; i < n+1; i++) arr[i] = arr[i-1] + arr[i-2];
return arr[n];
}
}
이렇게 배열로 선형적인 방식으로 값을 넣는데
호출 되는 것을 보면
n이 5일 때,
arr[0] = 0
arr[1] = 1
arr[2] = arr[0] + arr[1] = 0 + 1 = 1
arr[3] = arr[2] + arr[1] = 1 + 1 = 2
arr[4] = arr[3] + arr[2] = 2 + 1 = 3
arr[5] = arr[4] + arr[3] = 3 + 2 = 5
이렇게 됩니다.
애초에 배열에 값이 들어가게 되고 풀이 방식을 호출하는 것이 아닌,
메모리에 있는 값을 불러오는 것이기 때문에 시간이 덜 듭니다.
이와 같은 방식으로 피보나치 수 문제를 풀어보겠습니다.
programmers.co.kr/learn/courses/30/lessons/12945
코딩테스트 연습 - 피보나치 수
피보나치 수는 F(0) = 0, F(1) = 1일 때, 1 이상의 n에 대하여 F(n) = F(n-1) + F(n-2) 가 적용되는 수 입니다. 예를들어 F(2) = F(0) + F(1) = 0 + 1 = 1 F(3) = F(1) + F(2) = 1 + 1 = 2 F(4) = F(2) + F(3) = 1 + 2 = 3 F(5) = F(3) + F(4) =
programmers.co.kr
문제 설명
피보나치 수는 F(0) = 0, F(1) = 1일 때, 1 이상의 n에 대하여 F(n) = F(n-1) + F(n-2) 가 적용되는 수 입니다.
예를들어
- F(2) = F(0) + F(1) = 0 + 1 = 1
- F(3) = F(1) + F(2) = 1 + 1 = 2
- F(4) = F(2) + F(3) = 1 + 2 = 3
- F(5) = F(3) + F(4) = 2 + 3 = 5
와 같이 이어집니다.
2 이상의 n이 입력되었을 때, n번째 피보나치 수를 1234567으로 나눈 나머지를 리턴하는 함수, solution을 완성해 주세요.
제한 사항
* n은 1이상, 100000이하인 자연수입니다.
입출력 예
n | return |
3 | 2 |
5 | 5 |
입출력 예 설명
피보나치수는 0번째부터 0, 1, 1, 2, 3, 5, ... 와 같이 이어집니다.
package fibonachiNumber;
public class FibonachiNumber {
public static void main(String[] args) {
Solution s = new Solution();
System.out.println(s.solution(3));
System.out.println(s.solution(5));
}
}
class Solution {
public int solution(int n) {
int[] arr = new int[n+1];
arr[0] = 0;
arr[1] = 1;
if(n == 0) return arr[0];
else if(n == 1) return arr[1];
else {
for (int i = 2; i < n+1; i++) arr[i] = arr[i-1] % 1234567 + arr[i-2] % 1234567;
return arr[n] % 1234567;
}
}
}
'코딩테스트 > 프로그래머스' 카테고리의 다른 글
[프로그래머스/java] 영어 끝말잇기 (0) | 2021.03.12 |
---|---|
[프로그래머스/java] 이진 변환 반복하기 (0) | 2021.03.12 |
[프로그래머스/java] 월간 코드 챌린지 시즌1 삼각 달팽이 (0) | 2021.03.10 |
[프로그래머스/java] 2018 KAKAO BLIND RECRUITMENT [3차] n진수 게임 (0) | 2021.03.09 |
[프로그래머스/java] 체육복(탐욕법) (0) | 2021.01.29 |
댓글