프로그래밍적 표현 : S(a, b) = a[a] + a[a+1] + ... + a[b-1] + a[b]
이 두 개념이 누적합 알고리즘의 기초가 됩니다. 여기서 의문이 드실 수 있습니다.
"단순히 반복문으로 더하면 되지 않을까요?"
맞습니다. 단순하게 접근하면 그렇습니다. 하지만 지금부터 설명드릴 누적합 알고리즘을 활용하시면,
반복문으로 인한 시간 복잡도 문제를 효과적으로 해결하실 수 있습니다.
누적합 PrefixSum
array
1
2
3
4
5
6
7
8
9
…
prefix sum
1
3
6
10
15
21
28
36
45
…
자연수가 나열된 1차원 수열 (array)이 있을 때
이 수열에 대한 누적합 (prefixsum)
누적합은 나열된 수(수열)의 누적된 합 자체 혹은 그것을 담은 수열을 의미합니다.
또한, 누적합의 각 요소는 수열의 n번째까지 요소의 합이기 때문에 수열의 부분합이라고 할 수 있습니다.
자 그럼 누적합은 어떤 경우에 사용하기 위해서 만들어진 걸까요?
누적합 방식은 아래 유형의 문제 해결에 주로 사용됩니다.
구간합 / 부분합 (PartialSum)
카운팅 정렬 (CountingSort)
이제 1차원 수열과 2차원 수열로 나누어 예시를 보며 어떻게 만들고 사용하는지 배워봅시다.
1차원 배열에서의 누적합
1차원 배열의 누적합을 만드는 방법은 아주 간단합니다.
같은 크기의 배열을 만듭니다.
해당 인덱스까지의 총합을 담습니다.
자바스크립트에선 아래와 같이 작성할 수 있습니다.
function prefixSums(arr) { const len = arr.length; const prefixSums = []; let sum = 0; for (let i = 0; i < len; ++i) { sum += arr[i]; prefixSums[i] = sum; } return prefixSums;}
만약 sum변수를 만들지 않고 싶다면 아래와 같이 작성할 수 있습니다.
function prefixSums(arr) { const len = arr.length; const prefixSums = [arr[0]]; for (let i = 1; i < len; ++i) { prefixSums[i] = prefixSums[i - 1] + arr[i]; } return prefixSums;}