HyunsooZo's TIL logo HyunsooZo's TIL

알고리즘

슬라이딩 윈도우 란?

SW

슬라이딩 윈도우 알고리즘은 고정 크기의 윈도우를 사용하여
순차적으로 배열이나 리스트 등에서 데이터를 처리하는 기법이다.
이 기법은 연속된 부분 집합에서 최적의 결과를 찾는 데 사용된다.

일반적으로 슬라이딩 윈도우 알고리즘은 선형 데이터 구조(배열, 연결 리스트)에서 연속적인 부분 집합을 탐색하면서
특정 조건이나 규칙을 만족하는 부분 집합을 찾거나 최적화하는 데 사용된다.

알고리즘의 핵심 아이디어는 데이터 구조를 순차적으로 탐색하면서
윈도우의 시작과 끝을 조절하여 최적의 결과를 찾는 것인데
보통 윈도우의 크기는 고정되어 있으며, 시작과 끝을 조절하면서
데이터를 추가하거나 제거하여 윈도우 내의 데이터를 갱신한다.

이 알고리즘은 주로 부분 합, 부분 문자열, 연속된 구간 등의 문제에서 사용된다.
예를 들어, 최대값, 최소값, 평균 등을 구하는 문제, 특정 조건을 만족하는 가장 긴 부분집합을 찾는 문제 등에 슬라이딩 윈도우 알고리즘이 적용될 수 있다.

주로 두 개의 포인터를 사용하여 시작과 끝을 조절하고,
새로운 요소를 윈도우에 추가하거나 현재 윈도우의 요소를 제거하는 방식으로 동작한다.
이를 통해 선형 시간복잡도에 문제를 효율적으로 해결할 수 있다.

시간복잡도는 O(n)이므로 한번의 순회로 원하는 조건을 만족하는 부분집합을 찾거나 최적화하는데 사용될 수 있다.

프로그래머스 문제

연속된 부분 수열의 합

문제 설명

비내림차순으로 정렬된 수열이 주어질 때, 다음 조건을 만족하는 부분 수열을 찾으려고 합니다.

기존 수열에서 임의의 두 인덱스의 원소와 그 사이의 원소를 모두 포함하는 부분 수열이어야 합니다. 부분 수열의 합은 k입니다. 합이 k인 부분 수열이 여러 개인 경우 길이가 짧은 수열을 찾습니다. 길이가 짧은 수열이 여러 개인 경우 앞쪽(시작 인덱스가 작은)에 나오는 수열을 찾습니다. 수열을 나타내는 정수 배열 sequence와 부분 수열의 합을 나타내는 정수 k가 매개변수로 주어질 때, 위 조건을 만족하는 부분 수열의 시작 인덱스와 마지막 인덱스를 배열에 담아 return 하는 solution 함수를 완성해주세요. 이때 수열의 인덱스는 0부터 시작합니다.

제한사항

5 ≤ sequence의 길이 ≤ 1,000,000 1 ≤ sequence의 원소 ≤ 1,000 sequence는 비내림차순으로 정렬되어 있습니다. 5 ≤ k ≤ 1,000,000,000 k는 항상 sequence의 부분 수열로 만들 수 있는 값입니다.

문제분석

연속된 부분 수열 문제: 문제는 연속된 부분 수열에서 조건을 만족하는 부분을 찾는 것입니다.
슬라이딩 윈도우는 연속된 부분 수열 문제에 사용되는 일반적인 알고리즘 중 하나입니다.
선형 시간 복잡도: 슬라이딩 윈도우 알고리즘은 대부분의 경우 선형 시간 복잡도를 가집니다(O(n)). 따라서 수열의 크기가 크더라도 효율적으로 문제를 해결할 수 있습니다.

문제풀이
import java.util.*;
class Solution {
    public int[] solution(int[] sequence, int k) {
        int[] answer = new int[]{0,0};
        
        int sequenceLen = sequence.length, minLen = 1000001;
        
        int start = 0 ,end = 0 ,total = 0;
        
        while(end < sequenceLen) {
            total += sequence[end];
            while(total >= k) {
                if(total == k && end-start < minLen){
                    minLen = end - start;
                    answer[0] = start;
                    answer[1] = end;
                }
                total -= sequence[start];
                start ++;
            }
            end++;
        }
        
        return answer;
    }
}

sequence 배열을 순회하면서 start와 end 인덱스를 조정하여 윈도우를 이동시킵니다.
start와 end 사이의 부분 배열의 합이 k와 같거나 크면 조건을 만족합니다.
이때의 부분 배열 길이가 최소값보다 작으면(end - start) 해당 윈도우의 시작과 끝을 answer 배열에 저장합니다.
그 후, start를 증가시키면서 윈도우를 이동시킵니다.
end를 증가시키면서 윈도우의 끝을 이동시킵니다.

TOP