728x90
반응형
슬라이딩 윈도우(Sliding Window)
슬라이딩 윈도우(Sliding Window) 기법은 배열이나 문자열에서 연속된 구간(subarray, substring) 을 다룰 때 매우 유용한 최적화 알고리즘입니다.
이 글에서는 슬라이딩 윈도우의 개념, 종류, 구현 방법, 그리고 다양한 언어별(파이썬, C++, 자바, 자바스크립트) 실습 예제까지 제공하여, 초급부터 중급 개발자까지 쉽게 이해하고 응용할 수 있도록 돕겠습니다.
1. 슬라이딩 윈도우란?
슬라이딩 윈도우는 일정 범위(구간)를 유지하면서, 그 구간을 배열이나 문자열 위에서 한 칸씩 이동(slide) 시키는 기법입니다. 이 방식을 사용하면, 모든 구간을 새로 계산하지 않고, 이전 구간의 정보를 활용해 빠르게 결과를 업데이트할 수 있습니다.
기본 아이디어
- 초기 윈도우를 설정합니다.
- 윈도우를 한 칸 이동할 때마다, 새롭게 추가된 값과 제거된 값을 이용해 계산을 빠르게 갱신합니다.
이 과정을 통해 시간 복잡도를 줄여 O(N) 시간에 문제를 해결할 수 있습니다. (브루트 포스 대비 압도적으로 빠름)
슬라이딩 윈도우가 필요한 상황
- 배열 또는 문자열에서 고정 길이의 최대/최소 합 구하기
- 조건을 만족하는 최소/최대 길이의 부분 구간 찾기
- 부분 문자열 문제 해결
- 이동 평균(moving average) 계산
2. 슬라이딩 윈도우 유형 정리
유형 | 설명 | 예시 문제 |
고정 크기(Fixed-size) 윈도우 | 윈도우 크기가 항상 일정 | 최대 합 구하기, 이동 평균 |
가변 크기(Variable-size) 윈도우 | 조건에 따라 윈도우 크기가 변함 | 최소 길이 부분 배열, 가장 긴 부분 문자열 |
3. 슬라이딩 윈도우 기본 패턴
a. 고정 크기 윈도우
- 초기 윈도우 설정 (0부터 k-1까지)
- 이후 한 칸씩 이동하면서 추가/제거
- 매 이동마다 결과를 업데이트
b. 가변 크기 윈도우
- 시작 포인터(start)와 끝 포인터(end) 사용
- 조건을 만족할 때까지 end를 확장
- 조건을 초과하면 start를 이동시키며 조정
4. 주요 언어별 예제 코드
문제 예시 : 길이 k인 부분 배열 중 최대 합을 구하라.
배열 [1, 3, 2, 6, -1, 4, 1, 8, 2]에서 길이 3짜리 부분 배열 중 최대 합은 4+1+8=13입니다.
a. Python (파이썬)
def max_sum_subarray(arr, k):
window_sum = sum(arr[:k])
max_sum = window_sum
for i in range(k, len(arr)):
window_sum += arr[i] - arr[i-k]
max_sum = max(max_sum, window_sum)
return max_sum
# 사용 예시
arr = [1, 3, 2, 6, -1, 4, 1, 8, 2]
print(max_sum_subarray(arr, 3)) # 출력: 13
b. C++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int maxSumSubarray(const vector<int>& arr, int k) {
int windowSum = 0, maxSum = 0;
for (int i = 0; i < k; i++) windowSum += arr[i];
maxSum = windowSum;
for (int i = k; i < arr.size(); i++) {
windowSum += arr[i] - arr[i-k];
maxSum = max(maxSum, windowSum);
}
return maxSum;
}
int main() {
vector<int> arr = {1, 3, 2, 6, -1, 4, 1, 8, 2};
cout << maxSumSubarray(arr, 3) << endl; // 출력: 13
}
c. Java (자바)
public class SlidingWindowExample {
public static int maxSumSubarray(int[] arr, int k) {
int windowSum = 0, maxSum = 0;
for (int i = 0; i < k; i++) windowSum += arr[i];
maxSum = windowSum;
for (int i = k; i < arr.length; i++) {
windowSum += arr[i] - arr[i-k];
maxSum = Math.max(maxSum, windowSum);
}
return maxSum;
}
public static void main(String[] args) {
int[] arr = {1, 3, 2, 6, -1, 4, 1, 8, 2};
System.out.println(maxSumSubarray(arr, 3)); // 출력: 13
}
}
d. JavaScript (자바스크립트)
function maxSumSubarray(arr, k) {
let windowSum = 0;
for (let i = 0; i < k; i++) {
windowSum += arr[i];
}
let maxSum = windowSum;
for (let i = k; i < arr.length; i++) {
windowSum += arr[i] - arr[i-k];
maxSum = Math.max(maxSum, windowSum);
}
return maxSum;
}
// 사용 예시
const arr = [1, 3, 2, 6, -1, 4, 1, 8, 2];
console.log(maxSumSubarray(arr, 3)); // 출력: 13
5. 슬라이딩 윈도우 vs 브루트 포스 비교
항목 | 브루트 포스 | 슬라이딩 윈도우 |
시간 복잡도 | O(NK) | O(N) |
특징 | 모든 부분 구간을 매번 새로 계산 | 이전 계산값을 활용하여 빠르게 갱신 |
장점 | 단순하고 구현이 쉬움 | 빠르고 효율적 |
단점 | 느림 (N, K가 클 때) | 조건 설정이 중요 |
6. 마무리
- 슬라이딩 윈도우는 고정 길이 또는 가변 길이 구간을 한 칸씩 이동시키며 효율적으로 탐색하는 기법입니다.
- 브루트 포스보다 훨씬 빠른 O(N) 시간 복잡도를 제공합니다.
- 주로 배열, 문자열 관련 최적화 문제에 활용됩니다.
- 구현 시 윈도우 관리와 경계 조건 체크에 유의해야 합니다.
728x90
반응형
'코딩테스트 > 알고리즘' 카테고리의 다른 글
[정렬] 꼭 알아야 할 7가지 정렬 알고리즘 비교 정리 (0) | 2025.05.02 |
---|---|
[Queue] 줄 서서 처리하는 선입선출(FIFO) 자료구조 (0) | 2025.04.29 |
[Stack] 쌓고 꺼내는 후입선출(LIFO) 자료구조 (0) | 2025.04.29 |
[투 포인터] 효율적인 배열 탐색의 비법 (0) | 2025.04.26 |
[구간 합] 빠르고 정확한 합계 계산 (0) | 2025.04.26 |