JavaScript/js 문법
js - 슬라이딩 윈도우(Sliding Window)
GREEN나무
2025. 6. 2. 23:35
728x90
슬라이딩 윈도우(Sliding Window)는 배열이나 문자열에서 연속된 범위(부분 구간)를 한 칸씩 옮겨가며 검사하는 기법입니다.
일정한 범위를 유지하면서 한 칸씩 앞으로 이동하므로 O(n) 시간복잡도로 문제를 효율적으로 해결할 수 습니다..
✅ 슬라이딩 윈도우 방식이란?
- 기존 방식 (slice 사용)
→ 매 반복마다 slice(ex : discount.slice(i, i + 10))를 새로 만들어서 처리 → 시간 복잡도 O(n * 10) (즉, 전체 탐색 n번 * 슬라이스 10) - 슬라이딩 윈도우 방식
→ 초기 윈도우 한번 만들고, 다음 윈도우는 앞 원소 빼고, 뒤 원소 추가하는 식으로 처리 → 시간 복잡도 O(n) 근접
✨ 문법 구조 요약
for (let i = 0; i < windowSize; i++) {
// 초기 윈도우 상태 구성
}
for (let i = windowSize; i < arr.length; i++) {
// 1. 이전 요소 제거
// 2. 새로운 요소 추가
// 3. 윈도우 조건 검사
}
✨ 예시
const arr = [1, 2, 3, 4, 5];
const k = 3;
let sum = 0;
for (let i = 0; i < k; i++) sum += arr[i]; // 초기 윈도우
let maxSum = sum;
for (let i = k; i < arr.length; i++) {
sum += arr[i] - arr[i - k]; // 한 칸 밀면서 상태 갱신
maxSum = Math.max(maxSum, sum);
}
console.log(maxSum); // 12 (3+4+5)
🔁 슬라이딩 윈도우 적용 코드
const solution = (want, number, discount) => {
const wantMap = {};
want.forEach((item, i) => wantMap[item] = number[i]);
const windowMap = {};
for (let i = 0; i < 10; i++) {
windowMap[discount[i]] = (windowMap[discount[i]] || 0) + 1;
}
let count = 0;
const isMatch = () => {
return want.every(item => (windowMap[item] || 0) === wantMap[item]);
};
if (isMatch()) count++;
for (let i = 10; i < discount.length; i++) {
const removeItem = discount[i - 10];
windowMap[removeItem]--;
if (windowMap[removeItem] === 0) delete windowMap[removeItem];
const addItem = discount[i];
windowMap[addItem] = (windowMap[addItem] || 0) + 1;
if (isMatch()) count++;
}
return count;
};
✅ 장점
항목 | 설명 |
✅ 성능 개선 | slice() 없이 Map만 수정하므로 전체 연산이 O(n)에 근접 |
✅ 메모리 절약 | 매번 새 배열을 만들지 않음 |
✅ 반복된 연산 제거 | 동일한 윈도우 상태에서 불필요한 중복 계산 제거 |
❌ 단점
항목 | 설명 |
❌ 코드 복잡도 증가 | 초보자 입장에서는 Map 관리, 원소 제거/추가 등의 로직이 더 복잡해짐 |
❌ 버그 가능성 | 상태 관리(count, Map 수정 등) 실수 시 논리 오류가 생기기 쉬움 |
❌ 특정 문제에 부적합 | 윈도우 크기가 자주 바뀌거나, 불연속된 영역을 처리할 때는 적합하지 않음 |
📌 결론
- 데이터 양이 크고, 매번 같은 크기의 연속된 범위를 탐색해야 한다면 → 슬라이딩 윈도우 필수
- 다만, 코드의 가독성이 조금 떨어질 수 있으므로 가독성과 성능의 균형을 고려해 선택하면 됨
조건 | 슬라이딩 윈도우 성능 |
단순 누적합, 빈도 카운트 등 | ✅ 빠름 (O(n)) |
복잡한 상태 유지 (정렬, 중간값 등) | ⚠️ 느려질 수 있음 |
가변 윈도우 크기 문제 | ❌ 적합하지 않음 |
윈도우 크기가 배열과 거의 같음 | ❌ 효과 미미 |