본문 바로가기

Coding Test/Step21. 재귀

[Java] 1단계. 팩토리얼 2 [27433번]

728x90

https://www.acmicpc.net/problem/27433

  • 예제 입력1
10
  • 예제 출력1
3628800
  • 예제 입력2
0
  • 예제 출력2
1

  • 문제 접근
    • 재귀에서 가장 중요한 점은 종료하는 조건
    • 종료 조건을 제대로 설정하지 않으면 무한 재귀에 빠지며 StackOverFlow가 발생하게 됨
    • 입력
      • 정수 N (0 <= N <= 20)
    • 출력
      • N!
  • 문제 해결
    • 종료 조건 : N의 값이 1이하일 경우 1을 return
    • 단, N의 값이 '13'이면 62억을 넘어 int의 범위를 벗어나게 됨
    • 따라서, long의 값으로 계산해야 함
  • 기존 풀이 [메모리 : 14,172 KB / 시간 : 104 ms]
public static void main(String[] args) throws IOException{
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    int N = Integer.parseInt(br.readLine());

    System.out.println(recursive(N));
}

private static long recursive(int N) {
    if(N <= 1) {
        return 1;
    }
    return N * recursive(N-1);
}
  • Stream 풀이 [메모리 : 14,216 KB / 시간 : 104 ms]
public static void main(String[] args) throws IOException{
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    int N = Integer.parseInt(br.readLine());

    long factorial = LongStream.rangeClosed(1, N)
            .reduce(1, (a, b) -> a * b);

    System.out.println(factorial);
}
  • reduce의 원형 → T redcue(T identity, BinaryOperator<T> accumulator)
  • reduce(1, (a, b) → a * b) 해석
    • a : 초기값은 1로 누산기 역할
    • b : 스트림에서 가져온 값
    • 스트림에서 가져온 값 : LongStream.rangeClosed(1, 5) = 1, 2, 3, 4, 5로 b = 1, b = 2, ... , b = 5를 순차적으로 대입함
  • 이처럼 Stream으로 풀이를 하게 되면 재귀 호출 없이 반복적인 연산이 가능하여 StackOverflowError가 발생하지 않으며, 코드가 간결해진다는 장점이 있다고 함

728x90