안녕하세요! 이번 포스팅에서는 자바를 활용한 코딩테스트 준비를 위한 구간 합 문제를 다루어 보겠습니다. 구간 합 문제는 주어진 배열의 특정 구간에 있는 원소들의 합을 효율적으로 구하는 문제로, 알고리즘 문제에서 자주 출제되는 유형입니다.
문제 설명
배열 A
가 주어졌을 때, Q
개의 쿼리가 있습니다. 각 쿼리는 두 정수 L
과 R
로 이루어져 있으며, 이들은 배열 A
의 인덱스를 나타냅니다. 각 쿼리에 대해 L
번째부터 R
번째까지의 구간 합을 구하시오.
입력
첫 번째 줄에는 배열의 크기N
과 쿼리의 수Q
가 주어진다. 두 번째 줄에는N
개의 정수A[1], A[2], ..., A[N]
이 주어진다. 이후Q
개의 줄에L
과R
가 공백으로 구분되어 주어진다.
출력
각 쿼리에 대한 구간 합을 한 줄에 하나씩 출력한다.
예제 입력
5 3 1 2 3 4 5 1 3 2 4 1 5
예제 출력
6 9 15
문제 해결 전략
구간 합 문제를 처리하기 위한 코딩 방법은 여러 가지가 있지만, 비효율적인 방법으로는 각 쿼리에 대해 직접 루프를 돌며 구간 합을 계산하는 것입니다. 이 경우, 최악의 경우 O(N * Q)
의 시간이 소요될 수 있습니다. 따라서 우리는 구간 합을 빠르게 계산하기 위한 방법을 찾아야 합니다.
전처리 통한 접근
효율적인 방법 중 하나는 전처리 과정을 통해 구간 합을 누적 배열 형태로 저장하는 것입니다. 이렇게 하면 각 쿼리의 구간 합을 O(1)
에 구할 수 있습니다.
- 먼저, 누적합 배열
sum
을 생성합니다. 이때sum[0] = 0
으로 초기화하고,sum[i] = sum[i - 1] + A[i - 1]
로 설정합니다. - 각 쿼리는 구간
[L, R]
에서의 합을 구하기 위해sum[R] - sum[L - 1]
공식을 사용합니다.
자바 코드 구현
import java.util.Scanner; public class RangeSum { public static void main(String[] args) { Scanner sc = new Scanner(System.in); // 배열의 크기와 쿼리 수 입력 int N = sc.nextInt(); int Q = sc.nextInt(); // 배열 입력 int[] A = new int[N]; for (int i = 0; i < N; i++) { A[i] = sc.nextInt(); } // 누적합 배열 생성 long[] sum = new long[N + 1]; for (int i = 1; i <= N; i++) { sum[i] = sum[i - 1] + A[i - 1]; } // 각 쿼리를 처리 for (int i = 0; i < Q; i++) { int L = sc.nextInt(); int R = sc.nextInt(); long rangeSum = sum[R] - sum[L - 1]; System.out.println(rangeSum); } sc.close(); } }
코드 설명
위의 코드는 다음과 같은 흐름으로 동작합니다:
- 먼저, 사용자로부터 배열의 크기
N
과 쿼리 수Q
를 입력받습니다. - 그 다음, 배열
A
의 원소를 입력받아 초기화합니다. - 각 원소의 누적합을 저장하는
sum
배열을 생성합니다. 이때, 인덱스 0은 0으로 초기화 통합하여,sum[i]
에 대한 접근이 용이합니다. - 쿼리마다 주어진
L
과R
을 이용해 구간 합을 계산 후 출력합니다.
테스트 및 검증
코드를 작성한 후, 다양한 입력을 통해 각 쿼리가 올바른 결과를 출력하는지 확인해야 합니다. 예제 입력과 함께 추가적인 경우들도 실험해보며 결과를 검토합니다. 아래는 몇 가지 예시입니다.
- 입력:
1 1
→ 출력:1
- 입력:
2 5
→ 출력:14
- 입력:
3 3
→ 출력:3
결론
이번 포스팅에서는 구간 합 문제를 해결하는 과정을 살펴보았습니다. 전처리를 통해 구간 합을 효율적으로 계산하는 방법을 익히는 것이 중요하며, 자바의 배열과 반복문을 활용하는 방법을 연습하는 것도 좋은 코딩 실력을 기르는 데 도움이 될 것입니다. 앞으로 더 많은 알고리즘 문제를 다루며 기술적인 역량을 다져나가길 바랍니다.
감사합니다!