[백준] 11659번: 구간 합 구하기 4 (JavaScript)

2025. 2. 19. 15:19·PS

 

 


 

문제

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

 

 

개념

누적 합

 

 

실행 결과

12
9
1

 

 

 

 

 

구현 코드(JavaScript)

const fs = require('fs');

// 백준 제출용
let input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');

// 로컬 테스트용
// const filePath =
//   process.platform === 'linux' ? '/dev/stdin' : __dirname + '/input.txt';
// const input = fs.readFileSync(filePath).toString().trim().split('\n');

// 백준 11659번: 구간 합 구하기 4
const [n, m] = input[0].split(' ').map(Number);
const arr = input[1].split(' ').map((i) => +i);
const lines = input.slice(2);

const prefixSum = Array(n + 1).fill(0); // 구간합 배열
prefixSum[0] = arr[0];
for (let start = 1; start < n; start++) {
  prefixSum[start] = prefixSum[start - 1] + arr[start];
}

lines.forEach((line) => {
  const [i, j] = line.split(' ').map((v) => +v);

  // 단일 구간
  if (i === 1) {
    console.log(prefixSum[j - 1]);
  }
  // 여러 구간: prefixSum[j-1] - prefixSum[i-2]
  else {
    console.log(prefixSum[j - 1] - prefixSum[i - 2]);
  }
});

 

 

 

 

코드 설명

맨 처음에는 단순히 반복문으로 sum을 구하는 식으로 구현했는데, 시간초과가 발생했다.

그 이유는 각 반복마다 O(n)의 시간복잡도가 발생하기 때문이다.

 

이를 해결하기 위해 누적 합을 사용했다. 

 

누적 합(Prefix Sum)

누적합은 배열 내 원소의 값이 변하지 않고 그대로 유지될 때, 특정 구간 내 합을 구하는 데 사용할 수 있다.

왜냐하면 배열 내 원소 값이 바뀌지 않는다면, 누적된 합도 바뀌지 않을 것이기 때문이다.

 

따라서 반복문을 돌면서 그때그때 누적 값을 구하기보다, 미리 구간 별 합이 정의된 누적합 배열을 선언해두고, 필요할 때 인덱스를 이용하는 식으로 구현하면 시간복잡도를 훨씬 개선할 수 있다.

 

개선 전

lines.forEach((line) => {
  const [i, j] = line.split(' ').map((v) => +v);
  let sum = []; // 구간합 합배열

  sum[0] = arr[0];
  for (let k = 1; k < n; k++) {
    sum[k] = sum[k - 1] + arr[k];
  }
  ...

 

이런 식으로 주어진 라인 별로 반복문 쿼리를 돌면서 합을 계산하는 경우, 불필요하게 시간복잡도가 증가할 수 있다.

 

 

누적합을 사용해 개선된 후

먼저 1부터 N까지의 배열 내 원소들을 구간별로 누적해둔 합 배열을 따로 선언한다.

이 선언을 쿼리문 밖에서 진행하여, 시간복잡도를 개선할 수 있다.

const prefixSum = Array(n + 1).fill(0); // 구간합 배열
prefixSum[0] = arr[0];
for (let start = 1; start < n; start++) {
  prefixSum[start] = prefixSum[start - 1] + arr[start];
}

 

index 1부터 시작하여, 이전 원소 누적값에서 현재 탐색하고 있는 시점의 배열 원소값을 추가하는 방식으로 구현할 수 있다.

개인적으로 구현 방법이 dp와 비슷하다고 느껴졌다.

 

lines.forEach((line) => {
  const [i, j] = line.split(' ').map((v) => +v);

  // 단일 구간
  if (i === 1) {
    console.log(prefixSum[j - 1]);
  }
  // 여러 구간: prefixSum[j-1] - prefixSum[i-2]
  else {
    console.log(prefixSum[j - 1] - prefixSum[i - 2]);
  }
});

 

구간 시작과 끝 인덱스를 각각 i, j라고 하자.

만약 i가 1이라면 크게 생각할 필요 없이 끝 인덱스만 생각하면 된다.

 

하지만 중간 구간일 경우, 누적합 배열에서 다음과 같이 뺄셈해야 한다.

 

idx 1 2 3 4 5
arr[idx] 5 4 3 2 1
prefixSum 5 9 12 14 15

 

문제에서 주어진 테스트케이스를 생각해보자.

먼저 (1, 3)의 경우 5, 4, 3을 더해서 12가 나와야 한다.

이는 누적합 배열의 3번째 원소인 12와 같다.

 

두번째 테스트케이스는 (2, 4)로, 4+3+2 = 9가 나온다.

이는 prefixSum[4] - prefixSum[1] =  14 - 5 = 9 와 같은 결과이다.

 

마찬가지로 세번째 테스트케이스는 (5, 5)인데, 이는 prefixSum[5]-prefixSum[4] = 15-14 = 1과 같다.

즉, 이를 점화식으로 나타내면 prefixSum[끝 인덱스 - 1] - prefixSum[시작 인덱스 - 1]이라고 할 수 있다.

 

 


 

저작자표시 비영리 동일조건 (새창열림)

'PS' 카테고리의 다른 글

[백준] 1062번: 연결 요수의 개수 (JavaScript)  (0) 2025.02.20
[백준] 13904번: 과제 (JavaScript)  (0) 2025.02.20
[SWEA] 6808번: 규영이와 인영이의 카드게임 (Java)  (0) 2025.02.18
[백준] 15926번: 현욱은 괄호왕이야!! (JavaScript)  (0) 2025.02.16
[백준] 1914번 - 하노이 탑 (JavaScript)  (0) 2025.02.12
'PS' 카테고리의 다른 글
  • [백준] 1062번: 연결 요수의 개수 (JavaScript)
  • [백준] 13904번: 과제 (JavaScript)
  • [SWEA] 6808번: 규영이와 인영이의 카드게임 (Java)
  • [백준] 15926번: 현욱은 괄호왕이야!! (JavaScript)
abyss-s
abyss-s
프론트엔드 개발합니다!
  • abyss-s
    abyss-s의 블로그입니다.
    abyss-s
  • 전체
    오늘
    어제
    • 분류 전체보기 (190)
      • Web (16)
        • JavaScript (6)
        • TypeScript (1)
        • React (5)
        • Vue (0)
        • Storybook (1)
        • Next.js (1)
      • Backend & Infra (8)
        • Database (3)
        • Node.js (2)
        • SpringBoot (1)
      • PS (71)
      • CS (30)
        • OS (13)
        • Structure & Algorithm (5)
        • Network (10)
        • 정보처리기사 (2)
      • Language (18)
        • OOP (1)
        • JAVA (13)
        • C++ (4)
      • Activities (14)
        • 멋쟁이 사자처럼 (2)
        • OSSCA (3)
        • LG U+ URECA (5)
        • Project (2)
      • AI (0)
      • Git & Github (5)
      • Notion (1)
      • IT (4)
      • Statistics (11)
      • Book (4)
      • Diary (1)
      • Game (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • 깃허브
    • 백준
    • 트위터
  • 공지사항

    • abyss-s의 티스토리에 오신 것을 환영합니다.
  • 인기 글

  • 태그

    Java
    OS
    통계학
    DP
    파이썬
    React
    생활코딩
    BFS
    자바스크립트
    github
    Python
    JavaScript
    네트워크
    백준
    BAEKJOON
    C++
    운영체제
    그리디
    자바기반응용프로그래밍
    코드트리
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
abyss-s
[백준] 11659번: 구간 합 구하기 4 (JavaScript)
상단으로

티스토리툴바