프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
문제 설명
효진이는 멀리 뛰기를 연습하고 있습니다. 효진이는 한 번에 1칸, 또는 2칸을 뛸 수 있습니다. 칸이 총 4개 있을 때, 효진이는
(1칸, 1칸, 1칸, 1칸)
(1칸, 2칸, 1칸)
(1칸, 1칸, 2칸)
(2칸, 1칸, 1칸)
(2칸, 2칸)
의 5가지 방법으로 맨 끝 칸에 도달할 수 있습니다. 멀리뛰기에 사용될 칸의 수 n이 주어질 때, 효진이가 끝에 도달하는 방법이 몇 가지인지 알아내, 여기에 1234567을 나눈 나머지를 리턴하는 함수, solution을 완성하세요. 예를 들어 4가 입력된다면, 5를 return 하면 됩니다.
제한 사항
- n은 1 이상, 2000 이하인 정수입니다.
입출력 예
n | result |
4 | 5 |
3 | 3 |
입출력 예 설명
입출력 예 #1
위에서 설명한 내용과 같습니다.
입출력 예 #2
(2칸, 1칸)
(1칸, 2칸)
(1칸, 1칸, 1칸)
총 3가지 방법으로 멀리 뛸 수 있습니다.
풀이
처음에 재귀적 방식으로 풀었지만 시간 초과 나서 헤맸습니다. 몇 시간 헤매다가 질문 중 "피보나치 수 와 같은 문제다".라는 말을 보고 피보나치 수처럼 풀었더니 해결됐습니다.
class Solution {
fun solution(n: Int): Int {
if(n == 1)
return 1
val ary = Array<Int>(n){i -> 0}
ary[0] = 1
ary[1] = 2
for(i in 2 until ary.size){
ary[i] = (ary[i-1] + ary[i-2])%1234567
}
return ary[n-1]
}
}
이게 왜 피보나치 수의 일부가 나오는지 화학과 졸업 후 과외로 부업 뛰는 친구한테 물어본 결과 애초에 이런 방식으로 만들어진 수열이 피보나치수열인 것을 알게 됐습니다.
우선 문제를 분석해보면 계단 n 칸을 오르고 싶은데 1칸 아니면 2칸밖에 한 번에 못 올라갑니다. 따라서 n칸 오르는 경우의 수는 n-2칸까지 오르는 모든 경우의 수 에서 2칸 오르는 것과 n-1칸 까지 오르는 모든 경우의 수에서 1칸 오르는 것을 더하면 n칸 오르는 모든 경우의 수를 구할 수 있습니다.

이를 식으로 표현하게 되면 F(n) = F(n-1) + F(n-2)로 적을 수 있습니다. 매우 익숙한 공식이네요.
class Solution {
fun solution(n: Int): Int {
if(n == 1)
return 1
val ary = Array<Int>(n){i -> 0}
ary[0] = 1
ary[1] = 2
for(i in 2 until ary.size){
ary[i] = (ary[i-1] + ary[i-2])%1234567
}
return ary[n-1]
}
}
다시 문제로 돌아가서 n = 1일 경우 리턴 값은 1이고, n = 2일 경우 리턴값은 2입니다. 배열을 하나 만들어서 0번째 인덱스에 1, 1번째 인덱스에 2를 넣어줍니다. 숫자가 1씩 빠진 건 배열의 시작은 0이기 때문입니다. 이를 배열의 사이즈-1까지 만큼 반복해서 더해주게 되면 n칸까지 가는 모든 경우의 수를 구할 수 있습니다. n이 1일 때 1을 리턴해준 이유는 배열의 인덱스가 2보다 적기 때문에 바로 리턴해줬습니다.
후기
대학교 1학년 이산수학을 끝으로 수학에 손댄 적 없는데 시간 날 때마다 확률과 통계를 공부해야겠네요. 친구가 이건 조합으로 정의되네 하면서 공식을 보여줬는데 하나도 못 알아먹었습니다 ㅎㅎㅎㅎ

'코딩테스트 > 프로그래머스' 카테고리의 다른 글
예상대진표(Lv.2) (1) | 2022.09.21 |
---|---|
N개의 최소 공배수 (0) | 2022.09.20 |
피보나치 수(Lv.2) (0) | 2022.09.18 |
이진변환 반복하기(Lv.2) (0) | 2022.09.16 |
JadenCase 문자열 만들기(Lv.2) (1) | 2022.09.15 |