코딩테스트 슬라이딩 윈도우 풀이: 최대 매출 구간 합 계산하기

··설명 약 7분·작성: 해비·블로그 소개

읽기 전에 알아두면 좋아요

아래 개념이 익숙하면 본문을 바로 읽으세요. 낯선 개념만 링크에서 복습하면 됩니다.

개념과 예제는 실행하지 않아도 읽을 수 있습니다. 내 컴퓨터·터미널에서 직접 실행하는 과정은 선택 실습입니다.

과정 위치와 선택 복습 안내

과정 위치: 구간과 탐색 · 문제

과정 위치는 이 글이 속한 묶음입니다. 이 단계의 모든 개념을 먼저 읽을 필요는 없습니다. 위에 연결한 개념 중 낯선 내용만 복습하세요. 문제의 조건·상태·갱신 순서는 익숙한 언어로 설명하면 됩니다.

JavaScript로 문법·실행 복습하기 (선택)

개념 글의 코드는 JavaScript 예시입니다. 문제 화면에서는 JavaScript·Python·Java·C++·C# 중 익숙한 언어의 함수를 작성하세요. 본문의 Node.js 입출력 예시는 로컬 실행을 위한 별도 안내입니다.

최대 매출 문제는 매출 배열에서 길이가 k일인 연속 구간의 어떤 값을 구하나요?

매출 배열에서 연속한 k일의 매출 합 중 최댓값을 구하는 문제입니다. 배열·합계·최댓값의 기본을 준비하고, 아래 입력·반환 계약을 확인해 직접 풀어보세요.

적용 조건·범위: Q. 이 문제는 어떤 키워드에서 투 포인터를 떠올려야 하나요? 연속 구간, 고정 길이, 최대 합 같은 조건이 함께 나오면 슬라이딩 윈도우를 의심해볼 수 있습니다.

공식 문서 참고: 관련 개념: 고정 길이 슬라이딩 윈도우(8.3절)

문제 설명

코딩테스트 JS 슬라이딩 윈도우 풀이: 최대 매출 구간 합 계산하기 전반부 흐름 정리

현수의 아빠는 제과점을 운영합니다. 현수 아빠는 현수에게 N일 동안의 매출기록을 주고, 연속된 K일 동안의 최대 매출액이 얼마인지 구하라고 했습니다.

만약 N=10이고 10일 간의 매출기록이 아래와 같다면, 이때 K=3이면

12 15 11 20 25 10 20 19 13 15

연속된 3일간의 최대 매출액은 11 + 20 + 25 = 56 만원입니다.

여러분이 현수를 도와주세요.

입력 설명
첫 줄에 N(5 ≤ N ≤ 100,000)과 K(2 ≤ K ≤ N)가 주어집니다.
두 번째 줄에 N개의 숫자열이 주어집니다. 각 숫자는 500 이하의 음이 아닌 정수입니다.

출력 설명
첫 줄에 최대 매출액을 출력합니다.

입력 예제

10 3
12 15 11 20 25 10 20 19 13 15

출력 예제

56

원자료와 확인 범위

2026-10-12에 제공된 학습 자료 섹션 5. 효율성(투포인터 알고리즘, 슬라이딩윈도우, 해쉬).pdf의 5쪽 ‘최대 매출’와 문제 조건·예제를 대조했습니다. 같은 ZIP의 해당 문제 TXT는 풀이 코드 자료입니다. 이 자료의 최초 출제 원문·저자·공개 배포 주소까지 확인한 것은 아닙니다.

이번 대조는 원자료의 문제 조건과 예제 확인입니다. 이 글의 전체 코드를 새로 실행하거나 공식 채점에 제출한 결과를 뜻하지 않습니다. 아래 예제·자가 확인 항목은 직접 실행해 기대 출력과 비교하는 기준입니다.

직접 풀어보기

먼저 선택한 언어의 입력·반환 계약에 맞춰 작성해 보세요. 힌트 받기와 정답과 비교하기는 코드를 실행하지 않는 AI 분석입니다. 해답·해설은 아래에서 필요할 때 펼칠 수 있습니다.

0 / 6,000바이트

solution(k, arr)에 k(정수), arr(정수 배열)를 전달하고 정수를 반환합니다. 아래 문제의 유효 입력 조건을 따릅니다. 표준 입력과 출력 코드는 작성하지 않습니다. Tab은 다음 항목으로 이동합니다. 입력 영역 오른쪽 아래를 끌어 높이를 조절할 수 있습니다.

비밀키·개인정보는 입력하지 마세요. 코드는 이 페이지에만 유지됩니다.

해답·해설 보기
JavaScript 해답
function solution(k, arr) {
    let sum = 0;
    for (let i = 0; i < k; i++) sum += arr[i];
    let best = sum;
    for (let i = k; i < arr.length; i++) {
        sum += arr[i] - arr[i - k];
        best = Math.max(best, sum);
    }
    return best;
}

solution(k, arr)에 k(정수), arr(정수 배열)를 전달하고 정수를 반환합니다. 아래 문제의 유효 입력 조건을 따릅니다. 표준 입력과 출력 코드는 작성하지 않습니다.

내가 처음 작성한 풀이와 한계

코딩테스트 JS 슬라이딩 윈도우 풀이: 최대 매출 구간 합 계산하기 후반부 흐름 정리

문제를 처음 접했을 때, 가장 먼저 떠올린 방식은 시작 지점을 하나씩 옮기면서 K개의 값을 직접 더해보는 방법이었습니다. 실제로 이 방식으로 코드를 작성했고, 예제 입력에 대해서는 정답이 올바르게 출력되었습니다.

function solution(k, arr) {
  let result = 0;
  let start = 0;

  while (start <= arr.length - k) {
    let sum = 0;
    for (let i = 0; i < k; i++) {
      sum += arr[start + i];
    }
    result = Math.max(result, sum);
    start++;
  }

  return result;
}

이 코드가 헷갈리기 쉬운 이유는, “정답은 맞기 때문”입니다. 실제로 모든 연속된 K개의 구간을 빠짐없이 확인하기 때문에 논리적으로 틀린 풀이는 아닙니다.

하지만 문제의 핵심은 단순히 정답을 구하는 것이 아니라, 제한된 시간 안에 얼마나 효율적으로 계산할 수 있는지에 있습니다. 위 코드는 구간을 한 칸 이동할 때마다 항상 K개의 값을 다시 더합니다.

예를 들어 K가 3일 때, 첫 번째 구간과 두 번째 구간은 대부분의 값이 겹칩니다. 그럼에도 불구하고 이 풀이는 겹치는 값까지 매번 다시 계산합니다. 이로 인해 같은 숫자를 여러 번 반복해서 더하게 됩니다.

입력 크기 N이 커질수록 이 반복 계산은 급격히 늘어납니다. 문제 조건상 N은 최대 100,000까지 가능하기 때문에, 이러한 방식은 시간 제한에 걸릴 가능성이 높습니다.

즉, 이 풀이는 “틀린 풀이”라기보다는 “문제에서 요구하는 수준의 효율을 만족하지 못하는 풀이”입니다. 이 점을 인식하지 못하면, 왜 투 포인터를 써야 하는지 이해하기 어렵습니다.

투 포인터 풀이 구조

function solution(k, arr) {
  let sum = 0;

  // 초기 윈도우 합 만들기
  for (let i = 0; i < k; i++) {
    sum += arr[i];
  }

  let max = sum;

  // 슬라이딩 윈도우 이동
  for (let rt = k; rt < arr.length; rt++) {
    sum += arr[rt];      // 새로 들어오는 값
    sum -= arr[rt - k];  // 빠지는 값
    max = Math.max(max, sum);
  }

  return max;
}

이 문제에서 투 포인터(슬라이딩 윈도우)를 사용한다는 것은, 연속된 K개의 값을 하나의 “창문”처럼 보고 그 창문을 한 칸씩 이동시키며 합을 관리한다는 의미입니다. 핵심은 매번 전체를 다시 계산하지 않고, 이전 계산 결과를 그대로 활용하는 데 있습니다.

사고 흐름을 단계별로 나누면 이해가 훨씬 쉬워집니다.

1단계: 첫 번째 구간 만들기
먼저 배열의 앞에서부터 K개의 값을 더해 최초의 구간 합을 만듭니다. 이 값은 이후 모든 비교의 기준이 됩니다.

let sum = 0;
for (let i = 0; i < k; i++) {
  sum += arr[i];
}
let max = sum;

이 시점에서 sum은 0번 인덱스부터 K-1 인덱스까지의 합을 의미합니다. 즉, 현재 윈도우는 [0 ~ K-1] 구간에 놓여 있습니다.

2단계: 창문을 한 칸씩 이동시키기
이제 구간을 한 칸 오른쪽으로 이동합니다.
이때 기존에 계산해 둔 sum 값에 새로 들어오는 값은 더하고, 구간에서 빠지는 값은 빼주기만 하면 됩니다.
그래서 매번 처음부터 다시 합을 구할 필요가 없습니다.

따라서 새로운 구간을 만들기 위해 필요한 작업은 단 두 가지입니다.

for (let rt = k; rt < arr.length; rt++) {
  sum += arr[rt];      // 새로 들어오는 값
  sum -= arr[rt - k];  // 구간에서 빠지는 값
  max = Math.max(max, sum);
}

여기서 rt는 항상 현재 구간의 오른쪽 끝을 가리킵니다. rt – k는 이번 이동에서 빠지는 이전 창의 왼쪽 값입니다. 추가·제거 후 현재 창의 왼쪽 끝은 rt – k + 1입니다. 이 점이 투 포인터 풀이를 간결하게 만드는 핵심입니다.

3단계: 왜 이 방식이 빠른가
각 반복에서 수행되는 연산은 덧셈 1번, 뺄셈 1번뿐입니다. 따라서 배열을 한 번만 순회하게 되고, 전체 시간 복잡도는 O(N)이 됩니다.

반면 이전 풀이처럼 매번 K개의 값을 다시 더하는 방식은, 같은 숫자를 계속 반복해서 계산하게 되어 입력이 커질수록 성능 차이가 크게 벌어집니다.

정리하면, 투 포인터 풀이의 본질은 “포인터를 움직이는 기술”이 아니라 이미 계산한 결과를 다시 쓰는 사고 방식입니다. 이 관점이 잡히면 비슷한 유형의 문제에서도 자연스럽게 슬라이딩 윈도우를 떠올릴 수 있습니다.

입력 배열과 계산용 공간

본문의 완성 함수는 이미 주어진 N개 매출 배열을 읽고 sum, max, 인덱스만 유지하므로 입력을 제외한 추가 공간은 O(1)입니다. 최대 합 숫자 하나를 반환하므로 출력도 O(1)입니다. 입력 배열까지 포함한 저장 공간은 O(N)이며, 표준 입력 문자열을 배열로 변환해 호출할 때는 그 문자열·토큰·배열의 저장도 포함해야 합니다. 매 이동마다 새 구간 배열을 만드는 코드는 아닙니다.

비교 정리 및 선택 기준

구분 특징
브루트포스 구현은 쉽지만 중복 계산이 많음
투 포인터 이전 결과를 재사용하여 효율적

연속된 구간 + 고정 길이라는 조건이 보이면, 브루트포스보다 투 포인터를 우선적으로 떠올리는 것이 좋습니다. 아직은 자연스럽지 않지만, 이런 유형을 반복해서 풀어보며 익숙해질 필요가 있다고 느꼈습니다.

투 포인터 기본형을 함께 복기하려면 JS 연속 구간 합 투 포인터를 먼저 다시 보시면 좋습니다.

배열의 연속 구간 합 구조 확장은 JS 연속부분수열 투 포인터에서 변형 형태로 이어집니다.

FAQ

Q. 이 문제는 어떤 키워드에서 투 포인터를 떠올려야 하나요?
연속 구간, 고정 길이, 최대 합 같은 조건이 함께 나오면 슬라이딩 윈도우를 의심해볼 수 있습니다.

Q. 투 포인터 풀이가 항상 더 좋은가요?
대부분 효율적이지만, 조건이 맞지 않으면 오히려 코드가 복잡해질 수 있어 문제 특성을 먼저 판단해야 합니다.

Q. 이런 문제를 빠르게 구분하는 연습 방법은?
문제를 읽을 때 길이가 고정된 연속 구간인지 먼저 체크하는 습관이 도움이 됩니다.

이 문제를 푼 뒤 확인하기

K=N인 경우와 최대 구간이 마지막 K개인 경우를 비교하고, 창에서 빠지는 값의 인덱스를 적어 보세요.

본문의 예제와 이 반례를 직접 실행해 예상 출력과 비교하고, 결과가 다르면 입력 조건과 반복 범위를 다시 확인하세요.

풀이 함수를 독립 실행해 확인합니다

선수 지식은 배열·조건문·반복문과 위에서 설명한 자료구조입니다. 투 포인터 풀이 구조의 완성 함수 블록 하나를 solution.cjs로 저장하고, 그 아래에 다음 호출을 붙입니다. 앞의 비교용 풀이와 같은 이름의 함수를 함께 붙이지 않습니다. 터미널에서 node solution.cjs로 실행합니다.

console.log(JSON.stringify(solution(...[2, [0, 0, 0, 8, 9]])));

이 변형 호출의 기대 JSON 출력은 17입니다. 기존 함수 블록의 console.log가 있으면 그 출력 다음 줄에서 확인합니다.

글 소개·학습 준비·전체 목차

주요 포인트 한눈에 보기

연속된 K일 동안의 매출 합 중 최댓값을 구하는 문제를 통해 투 포인터(슬라이딩 윈도우) 사고 흐름을 정리합니다. 브루트포스 접근 → 한계 인식 → 투 포인터 개선 과정을 단계적으로 비교합니다.

이 글이 도움이 되었나요?

조회 중

이어서 공부하기

체크포인트: 해설을 가리고 다시 풀고, 경계 입력을 하나 바꾸어 예상 결과와 실제 결과를 비교하세요. 포인터를 움직여도 답을 버리지 않는 이유와 양수·0·음수의 차이를 설명하세요.

다음 추천 · 문제: 투 포인터: 합이 M인 연속 부분수열 개수

같은 주제의 문제에 적용하며 방금 배운 개념을 확인합니다.

권장 순서는 학습 가이드와 같습니다. 다른 순서는 접힌 참고 목록에서 확인할 수 있습니다. 읽음 표시는 숙달이나 채점 결과가 아닙니다.

원래 과정 목록 순서 (선택)

읽음 기록

읽음 — / 전체 58개 · 필수 58개

이 글을 쓴 해비

웹사이트를 제작·운영하고, 개인 서비스와 자동화·AI 도구를 만듭니다. 직접 만들며 배운 내용과 문제 해결 과정을 BlogFlow에 기록합니다.

새 글 받아보기

RSS 리더에서 BlogFlow의 새 글을 확인할 수 있습니다.

RSS 피드 구독하기

댓글 남기기