프론트 개발자를 위한 여정

모든 영역을 안내하는 개발자

Algorithm

슬라이딩 윈도우(Sliding Window) 알고리즘 개념-고정크기,가변크기,투포인터 슬라이딩 윈도우

ji-frontdev 2025. 4. 2. 10:00
728x90
반응형

 

연속된 구간(부분 배열 또는 부분 문자열)을 다룰 때 사용되며, O(n)의 시간 복잡도로 효율적인 문제 해결이 가능합니다.


🔹 슬라이딩 윈도우 알고리즘 개념

💡 일반적인 접근법

  1. 초기 윈도우를 설정 (길이 k의 첫 번째 부분 배열 또는 문자열)
  2. 윈도우를 한 칸씩 이동하면서 이전 값은 제거하고 새로운 값을 추가
  3. 필요한 계산을 업데이트 (예: 합, 평균, 최대값, 최소값 등)
  4. 모든 윈도우에 대해 최적값을 찾음

💡 시간 복잡도

  • 단순 O(n * k) 브루트포스 접근법을 O(n)으로 최적화할 수 있음
  • 모든 원소를 한 번씩만 처리하므로 O(n)

🔹 슬라이딩 윈도우 알고리즘 유형

1️⃣ 고정 크기(Fixed Size) 슬라이딩 윈도우

📌 길이가 k인 고정된 윈도우를 이동시키며 계산하는 방식
📌 대표 문제: 최대/최소 합, 평균, 특정 조건을 만족하는 연속 부분 문자열

function maxSumSubarray(arr, k) {
    let maxSum = 0;
    let currentSum = 0;

    // 초기 윈도우 계산 (첫 k개의 합)
    for (let i = 0; i < k; i++) {
        currentSum += arr[i];
    }
    maxSum = currentSum;

    // 윈도우를 이동하며 업데이트
    for (let i = k; i < arr.length; i++) {
        currentSum += arr[i] - arr[i - k]; // 새로운 값 추가, 오래된 값 제거
        maxSum = Math.max(maxSum, currentSum);
    }

    return maxSum;
}

// 테스트
console.log(maxSumSubarray([2, 1, 5, 1, 3, 2], 3)); // 9 (5+1+3)
 

이해하기 쉬운 포인트

  • currentSum을 활용하여 이전 값을 빼고, 새 값을 더하면서 윈도우를 유지
  • 한 번만 순회하므로 O(n)

2️⃣ 가변 크기(Variable Size) 슬라이딩 윈도우

📌 윈도우 크기가 가변적이며 특정 조건을 만족할 때만 확장/축소
📌 대표 문제: 최소 길이 부분 배열 찾기, 특정 조건을 만족하는 연속 부분 문자열

function minSubarrayLen(arr, target) {
    let left = 0, sum = 0;
    let minLength = Infinity;

    for (let right = 0; right < arr.length; right++) {
        sum += arr[right];  // 우측 확장

        while (sum >= target) {  // 조건 충족 시 최소 길이 업데이트 후 축소
            minLength = Math.min(minLength, right - left + 1);
            sum -= arr[left];
            left++;  // 왼쪽 이동
        }
    }

    return minLength === Infinity ? 0 : minLength;
}

// 테스트
console.log(minSubarrayLen([2, 3, 1, 2, 4, 3], 7)); // 2 (4+3)

이해하기 쉬운 포인트

  • 우측을 확장하면서 합을 누적
  • 조건 충족 시 좌측을 줄이며 최소 길이 업데이트
  • while을 통해 특정 조건을 만족하는 최소 윈도우를 찾아냄

3️⃣ 투 포인터(Two Pointers)와 결합된 슬라이딩 윈도우

📌 투 포인터(Two Pointer)와 유사한 개념이지만, 윈도우 내부 조건을 최적화
📌 대표 문제: 두 개의 포인터로 최적 구간을 찾는 문제 (예: 부분 문자열, 배열 구간)

function longestSubstringWithoutRepeating(s) {
    let charSet = new Set();
    let left = 0, maxLength = 0;

    for (let right = 0; right < s.length; right++) {
        while (charSet.has(s[right])) {
            charSet.delete(s[left]);  // 중복 제거
            left++;
        }
        charSet.add(s[right]);
        maxLength = Math.max(maxLength, right - left + 1);
    }

    return maxLength;
}

// 테스트
console.log(longestSubstringWithoutRepeating("abcabcbb")); // 3 ("abc")

이해하기 쉬운 포인트

  • 중복 문자가 발생하면 좌측을 이동하여 해결
  • 윈도우 크기를 유지하면서 최적의 부분 문자열을 찾음

🔹 슬라이딩 윈도우 알고리즘의 장점

O(n)으로 최적화 가능 → 모든 원소를 한 번만 확인하며 처리
별도 리스트 저장 없이 O(1) 공간만 사용 가능
연속된 데이터 처리에 적합 (문자열, 배열, 시간 기반 데이터 등)


🔹 슬라이딩 윈도우를 사용하는 대표 문제

 

✅ 고정 크기 윈도우 최대 합 서브배열 주어진 길이의 부분 배열에서 최대 합 찾기
✅ 가변 크기 윈도우 최소 길이 부분 배열 특정 조건을 만족하는 최소 길이 찾기
✅ 투 포인터 결합 중복 없는 가장 긴 부분 문자열 같은 문자가 없는 가장 긴 연속 부분 문자열 찾기
✅ 모음 포함 부분 문자열 [findSubstring 문제 (네가 푼 문제!)] 특정 문자 개수를 만족하는 부분 문자열 찾기

🔹 정리

  1. 고정 크기(Fixed Size) → O(n) 유지하면서 k 길이 유지
  2. 가변 크기(Variable Size) → 조건을 만족하면 좌측을 축소하여 최적 길이 찾기
  3. 투 포인터 결합(Two Pointers) → 중복 없이 특정 속성을 유지하는 구간 찾기
728x90
반응형