https://school.programmers.co.kr/learn/courses/30/lessons/12945?language=javascript
피보나치 수는 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은 2 이상 100000 이하인 자연수 입니다.
처음엔 단순하게 재귀를 사용해서 해결하려고 시도했다.
function solution(n) {
let answer = 0;
const fibo = (num) => {
if (num === 0) return 0;
else if (num === 1) return 1;
else {
return fibo(num - 1) + fibo(num - 2);
}
};
answer = fibo(n);
return answer;
}
그 결과 7~14번 케이스에서 시간 초과와 런타임 에러로 인해 실패했다
n은 2 이상 100000 이하로 n의 크기가 커지면 시간복잡도상 비효율적이며, 피보나치 수의 결과가 int 의 범위를 넘어서 잘못된 결과를 리턴할 수 있다. 😅
그래서 dp를 활용해서 bottom-up 방식으로 접근했고, BigInt를 이용했다.
function solution(n) {
const cache = Array.from({ length: n });
// F(0) = 0, F(1) = 1이니 배열의 0~1번째 원소엔 해당 값으로 세팅해준다.
cache[0] = 0n;
cache[1] = 1n;
if (n < 2) return n;
for (let i = 2; i <= n; i++) {
cache[i] = cache[i - 1] + cache[i - 2];
}
return cache[n] % 1234567n;
}
이렇게 풀었더니 통과를 하긴 했는데..13, 14케이스에서 시간이 오래 걸리는 것을 확인할 수 있었다.
n번째 피보나치 수를 1234567로 나눈 나머지만 리턴하는 것이 아닌,
배열에 담아줄 때마다 1234567로 나눈 나머지값을 담아주도록 처리했다.
function solution(n) {
const cache = Array.from({length:n});
cache[0] = 0n;
cache[1] = 1n;
for(let i = 2; i <= n; i++){
cache[i] = (cache[i - 1]%1234567n) + (cache[i - 2]%1234567n);
}
return cache[n]%1234567n;
}
그 결과 시간이 확 줄어들었음!
위의 코드들은 BitInt도 같이 활용해서 풀었지만 사실 BigInt를 활용하지 않고 풀 수 있다.
( 1234567로 나눈 나머지 값만 잘 활용해도 풀 수 있다)
function solution(n) {
const cache = Array.from({length:n});
cache[0] = 0;
cache[1] = 1;
for(let i = 2; i <= n; i++){
cache[i] = (cache[i - 1]%1234567) + (cache[i - 2]%1234567);
}
return cache[n]%1234567;
}
이렇게 푸는 게 더 나은 것 같다! 😇
int 라는 자료형은 -2,147,483,648 ~ 2,147,483,647까지의 값만을 표현할 수 있다.
이 범위를 벗어나면 예상치 못한 이상한 결과가 나오게 된다.
제한 사항에서 n은 2 이상 100000 이하라는 조건이 주어졌으니 n의 크기가 크면 피보나치 수의 계산 결과도 그만큼 커질 것이고 int의 범위를 넘어설 가능성이 높다.
문제를 보면 1234567로 나눈 나머지를 출력하라고 하는데
만약 자료형의 크기에 제한이 있는 언어를 쓸 경우 저 특징을 활용해서 처리하라고 힌트를 준 것!
즉 (A + B) % C === ((A % C) + (B % C)) % C 라는 특징을 이용해서
매번 계산 결과에 1234567으로 나눈 나머지를 대신 넣어서 문제를 풀면 값이 int 범위를 넘어서지 않는 선에서 해결 할 수 있다.
[DFS] 바둑이 승자 (0) | 2023.11.05 |
---|---|
[프로그래머스] 2018 KAKAO BLIND RECRUITMENT - [1차] 비밀지도 (0) | 2023.05.25 |
[프로그래머스] 달리기 경주 (0) | 2023.04.14 |
[프로그래머스] 덧칠하기 (0) | 2023.04.12 |
[리트코드] A Better Repeated Deletion Algorithm (0) | 2023.04.10 |
댓글 영역