구간 합은 합 배열을 이용하여 시간 복잡도를 줄이기 위해 사용하는 알고리즘이다.
합 배열 S 정의
S[i] = A[0] + A[1] + .... A[i] // A[0]부터 A[i]까지의 합
합 배열을 구해 놓으면 기존 배열의 일정 범위의 합을 구하는 시간 복잡도가 O(N)에서 O(1)로 감소하게 된다.
합 배열 S를 만드는 법
S[i] = S[i-1] + A[i]
합 배열을 이용해 구간 합을 구하는 법
S[j] - [S-i] i에서 j까지의 구간 합
/*
ex)
2~5 까지의 구간 합
S[5] = A[0] + A[1] + A[2] + A[3] + A[4] + A[5]
s[1] = A[0] + A[1]
*/
문제
수 N개가 주어졌을 때, i번째 수부터 j번째 수까지 합을 구하는 프로그램을 작성하시오.
입력
첫째 줄에 수의 개수 N과 합을 구해야 하는 횟수 M이 주어진다. 둘째 줄에는 N개의 수가 주어진다. 수는 1,000보다 작거나 같은 자연수이다. 셋째 줄부터 M개의 줄에는 합을 구해야 하는 구간 i와 j가 주어진다.
출력
총 M개의 줄에 입력으로 주어진 i번째 수부터 j번째 수까지 합을 출력한다.
제한
- 1 ≤ N ≤ 100,000
- 1 ≤ M ≤ 100,000
- 1 ≤ i ≤ j ≤ N
수의 개수와, 합을 구해야 하는 횟수가 각각 최대 100,000회이므로 구간마다 합을 매번 계산하면 시간이 오래 걸린다.
그러므로 구간 합 알고리즘을 이용해야 한다.
답1
Scanner scan = new Scanner(System.in);
int num = scan.nextInt(); //데이터 개수
int quest = scan.nextInt(); //질의 개수
int[] arr = new int[num + 1]; //데이터 배열 생성
//배열 값 입력
for (int i = 1; i <= num; i++) {
arr[i] = scan.nextInt();
}
//구간 합 배열 구하기
int[] sumArr = new int[num + 1];
for (int i = 1; i <= num; i++) {
sumArr[i] = sumArr[i - 1] + arr[i];
}
//구간 합 구하기
for (int i = 0; i < quest; i++) {
int a = scan.nextInt();
int b = scan.nextInt();
System.out.println(sumArr[b] - sumArr[a - 1]);
}
위 코드를 조금 더 줄이는 방법은 배열을 생성하지 않고 값 입력과 동시에 합 배열을 생성하는 것이다.
답2
Scanner scan = new Scanner(System.in);
int num = scan.nextInt(); //데이터 개수
int quest = scan.nextInt(); //질의 개수
// 입력된 값을 바로 합 배열에 이용
int[] sumArr = new int[num + 1];
for (int i = 1; i <= num; i++) {
sumArr[i] = sumArr[i - 1] + (scan.next(int));
}
//구간 합 구하기
for (int i = 0; i < quest; i++) {
int a = scan.nextInt();
int b = scan.nextInt();
System.out.println(sumArr[b] - sumArr[a - 1]);
}
'코딩테스트' 카테고리의 다른 글
[백준 2018번] 연속된 자연수의 합 구하기 - 투 포인터 (1) | 2023.04.14 |
---|---|
[백준 11660번] 구간 합 구하기 5 (1) | 2023.04.12 |
Java를 이용하여 1 ~ N 숫자에서 소수 찾기 (0) | 2023.04.11 |
[프로그래머스] 문자열 정렬하기 (2) (0) | 2022.10.05 |
[프로그래머스] 약수 구하기 (1) | 2022.10.05 |
댓글