한양과학기술고등학교

에듀테크 프로젝트 대시보드

슬라이딩 윈도우 기법 (투 포인터)

슬라이딩 윈도우 기법 (투 포인터)

"연속된 구간"에 대한 질문은, 구간을 매번 처음부터 다시 세지 말고 한 칸 밀 때 나간 원소만 빼고 들어온 원소만 더하면 된다. 겹치는 계산을 재활용해 O(n·k)를 O(n)으로 낮추는, 코딩 테스트 단골 패턴.

이 "윈도우"는 네트워크의 그것과 다르다 — TCP 슬라이딩 윈도우는 "확인응답 없이 보낼 수 있는 바이트 범위"를 뜻하고, 여기서는 배열/문자열의 연속 부분구간을 훑는 알고리즘 기법이다. 이름만 같고 아이디어(범위를 통째로 옮긴다)만 닮았다.

1. 고정 크기 창 — "연속한 k개의 최대 합"

길이 k인 모든 연속 구간의 합 중 최댓값을 찾는다. 순진하게 풀면 구간마다 k번씩 더해 O(n·k). 슬라이딩 윈도우는 창을 오른쪽으로 한 칸 밀 때

새 합 = 이전 합 + arr[오른쪽 새 원소] − arr[왼쪽 빠지는 원소]

덧셈·뺄셈 딱 2번이면 되므로 전체가 O(n). 아래에서 초록은 새로 들어온 칸, 빨강은 창에서 빠지는 칸이다.

현재 창 합
–
지금까지 최대
–
슬라이딩 연산
0
순진한 방식이면
0
「한 칸 밀기」로 창을 오른쪽으로 옮겨 보세요.
순진한 O(n·k)
0회
슬라이딩 O(n)
0회

2. 가변 크기 창 — "합이 S 이상인 가장 짧은 구간"

이번엔 창의 크기가 정해져 있지 않다. 포인터 두 개(left, right)로 창을 관리한다.

창 합
0
창 길이
0
최단 길이 답
∞
포인터 이동
0
「한 단계」로 right를 늘려 창을 키우세요.

3. 문자열 창 — "중복 없는 가장 긴 부분문자열"

같은 아이디어를 문자열에 적용한다. right가 만난 글자가 창 안에 이미 있으면, 그 글자를 만날 때까지 left를 당겨 창에서 중복을 몰아낸다. 창은 항상 "서로 다른 글자들"만 담는다.

현재 창
""
가장 긴 길이
0
진행
0 / 0
「한 단계」로 오른쪽 글자를 창에 넣어 보세요.

4. 코드로 정리

고정 창 — 최대 구간 합

def max_window_sum(arr, k):
    win = sum(arr[:k])                 # 첫 창은 한 번만 직접 계산
    best = win
    for r in range(k, len(arr)):
        win += arr[r] - arr[r - k]     # 들어온 것 +, 나간 것 -
        best = max(best, win)
    return best                          # 전체 O(n)

가변 창 — 합 ≥ S 인 최단 길이

def shortest_subarray(arr, S):
    left = 0; win = 0; best = float('inf')
    for right in range(len(arr)):
        win += arr[right]                    # 창 확장
        while win >= S:                       # 조건 만족 → 최대한 수축
            best = min(best, right - left + 1)
            win -= arr[left]
            left += 1
    return best if best != float('inf') else 0
가변 창이 O(n)인 이유 — while 안이 아무리 여러 번 돌아도, left는 배열 전체에서 누적 n번까지만 증가할 수 있다. right도 n번. 그래서 총 연산은 2n 안쪽 → O(n). 중첩 반복문처럼 보여도 O(n²)이 아니다. (이걸 amortized 분석이라 부른다.)

5. 언제 쓸 수 있나 / 없나

쓸 수 있다쓰기 어렵다
연속된 부분배열/부분문자열이 대상 원소를 건너뛰어 고르는 부분수열
창을 넓히면 "좋아지고" 좁히면 "나빠지는" 단조성이 있음
(합, 개수, 서로 다른 문자 수 …)
음수가 섞여 합이 들쭉날쭉 → 가변 창의 단조성이 깨짐
(이땐 누적 합 + 자료구조)
"길이 k인", "합 ≥ S인", "중복 없는 최장" 같은 조건 구간 순서가 중요하지 않은 문제
한 줄 요약 — 연속 구간 문제에서 창을 한 칸 밀 때 차이만 갱신하면 O(n). 관련: Big-O 표기법, 이진 탐색, 투 포인터(토끼와 거북이), 토큰 버킷(시간 창).