자료구조 & 알고리즘/알고리즘

[알고리즘] Sliding Window

쉽코기 2021. 10. 29. 14:59

Sliding Window 

슬라이딩 윈도우는 연속적인 리스트나 배열의 원소들의 값들을 비교하기 위한 알고리즘입니다.

 

 

예제 >

현수의 아빠는 제과점을 운영합니다. 현수 아빠는 현수에게 N일 동안의 매출기록을 주고 연속된 K일 동안의 최대 매출액이 얼마인지 구하라고 했습니다.

만약 N=10이고 10일 간의 매출기록이 아래와 같습니다. 이때 K=3이면

[2, 4, 7, 10, 8, 4, 5, 6, 7, 1]

연속된 3일간의 최대 매출액은 7+10+8=25만원입니다.

 

직관적인 방법으로 구현한다면 다음과 같이 구할 수 있습니다.

 

public class Main {
    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);
        int size = scanner.nextInt();
        int range = scanner.nextInt();

        ArrayList<Integer> arrayList = new ArrayList<>();

        for (int i = 0; i < size; i++) {
            arrayList.add(scanner.nextInt());
        }

        int maxTotal = 0;

        for (int i = 0; i < arrayList.size() - range + 1; i++) {
            int temp = 0;
            for (int j = 0; j < range; j++) {
                temp += arrayList.get(i+j);
            }
            if (temp > maxTotal) {
                maxTotal = temp;
            }
        }
        System.out.println(maxTotal);

    }
}

 

이때 이중 포문이 돌기 때문에 시간 복잡도는 O(n^2) 이 됩니다.

그러나 중복된 부분을 삭제하고 한개의 포문으로 단순화 할 수 있습니다.

 

핵심은 매 순회마다 추가되는 인덱스와 삭제되는 인덱스가 일관성을 갖기 때문에 이를 계산하여 추가 삭제해줌으로 써 하나의 포문으로 구현가능합니다.

 

 

 public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);
        int size = scanner.nextInt();
        int range = scanner.nextInt();

        ArrayList<Integer> arrayList = new ArrayList<>();

        for (int i = 0; i < size; i++) {
            arrayList.add(scanner.nextInt());
        }

        int total = 0;
        int result = 0;

        for (int i = 0; i < range; i++) {
            total += arrayList.get(i);
        }

        result = total;

        for (int i = range ; i < arrayList.size(); i++) {
            total = total + arrayList.get(i) - arrayList.get(i - range );
            result = Math.max(result , total);
        }
        System.out.println(result);
    }