자바 코딩테스트 강좌, 이친수 구하기

이 글에서는 이친수에 대한 문제를 풀어보겠습니다. 이친수는 0과 1로 이루어진 수열로서, 특정한 조건을 만족해야 합니다. 이 문제는 자바 코딩 테스트에서 자주 출제되는 문제 중 하나이며, 다이나믹 프로그래밍(Dynamic Programming)을 이용하여 해결할 수 있습니다.

1. 문제 정의

문제: N자리 이친수의 개수를 구하는 프로그램을 작성하세요. 이친수는 다음과 같은 조건을 만족합니다:

  • 수의 첫 자리는 1이어야 한다.
  • 0과 1로만 구성되어야 한다.
  • 1이 두 개 이상 연속되어 있으면 안 된다.

예를 들어, 3자리 이친수는 100, 101, 110 세 가지가 있습니다. 4자리 이친수는 1000, 1001, 1010, 1100, 1101가 있습니다. 이 문제를 해결하는 방법을 살펴보겠습니다.

2. 접근 방법

이 문제를 해결하기 위해 다이나믹 프로그래밍(DP) 접근법을 사용할 수 있습니다. 이친수를 N자리로 만드는 방법은 다음과 같이 구성할 수 있습니다:

2.1. 상태 정의

하나의 이친수는 마지막 자리가 0일 때와 1일 때의 두 가지 경우로 나눌 수 있습니다. 따라서 다음과 같은 두 가지 DP 배열을 정의합니다.

  • dp0[i]: 길이가 i인 이친수 중 마지막 자리가 0인 수의 개수
  • dp1[i]: 길이가 i인 이친수 중 마지막 자리가 1인 수의 개수

이때, 전체 N자리 이친수의 개수는 dp0[N] + dp1[N]로 표현할 수 있습니다. 이친수를 구성하는 규칙성을 발견하여 다음과 같이 점화식을 도출할 수 있습니다:

2.2. 점화식

  • dp0[i] = dp0[i-1] + dp1[i-1] (i-1자리 이친수 중 마지막 자리가 0인 수와 1인 수를 합산)
  • dp1[i] = dp0[i-1] (i-1자리 이친수 중 마지막 자리가 0인 수만 가능)

2.3. 초기 조건

초기값은 다음과 같습니다:

  • dp0[1] = 0 (1자리 수 중 0으로 끝나는 경우는 없음)
  • dp1[1] = 1 (1자리 수 중 1로 끝나는 경우는 하나: 1)

3. 자바 코드 구현

이제 이 조건을 이용하여 자바로 구현해보겠습니다.

public class 이친수 {
    private static int[] dp0;
    private static int[] dp1;

    public static void main(String[] args) {
        int N = 4; // 입력: N 자리
        dp0 = new int[N + 1];
        dp1 = new int[N + 1];

        // 초기값 설정
        dp0[1] = 0;
        dp1[1] = 1;

        // DP 테이블 채우기
        for (int i = 2; i <= N; i++) {
            dp0[i] = dp0[i - 1] + dp1[i - 1];
            dp1[i] = dp0[i - 1];
        }

        // 결과 출력
        int result = dp0[N] + dp1[N];
        System.out.println("N자리 이친수의 개수: " + result);
    }
}

위 코드는 이친수를 구하는 프로그램의 전체 구조를 보여줍니다. 각 단계에서 DP 테이블을 채우고, 마지막에 결과를 출력하는 방식으로 구현했습니다.

4. 성능 분석

이 알고리즘의 시간 복잡도는 O(N)이며, 공간 복잡도 역시 O(N)입니다. 이친수를 구하는 데 있어서 매우 효율적인 방법을 제공하므로, 큰 N에 대해서도 빠른 수행이 가능합니다. 이 알고리즘은 다이나믹 프로그래밍과 점화식을 잘 활용하였다는 점에서 많은 다른 비슷한 문제에서도 응용이 가능할 것입니다.

5. 문제 변형

이 문제를 변형하여 여러 가지 다른 문제를 만들어 볼 수 있습니다. 예를 들어:

  • N자리 이친수의 배열을 반환하는 프로그램
  • 이친수의 모든 가능한 조합을 출력하는 프로그램
  • 주어진 수열이 이친수인지 여부를 판단하는 프로그램

6. 결론

오늘은 이친수를 구하는 방법에 대해 다루어 보았습니다. 이를 통해 다이나믹 프로그래밍의 개념과 이 패턴을 활용한 문제 해결 능력을 향상시킬 수 있기를 바랍니다. 향후 코딩 테스트와 알고리즘 문제 풀이에서 유용하게 활용될 것입니다.

7. 참고 자료