백준 11003 최솟값 찾기

https://www.acmicpc.net/problem/11003

최솟값 찾기 문제에서는 5,000,000개의 원소들에 대해서 구간(창의 크기가 5,000,000)개이므로 O(NN)이나 O(ND)로는 해결이 어렵다.

따라서 이 문제 해결을 위해서는 슬라이딩 윈도우 알고리즘을 사용한다. 보통 슬라이딩 윈도우 알고리즘이라 하면 두개의 포인터를 이용하여 해결하는 경우가 많지만, 적절한 자료구조를 사용하면 코드 이해가 편해지고 깔끔해지는 경우가 있다.

대략적인 알고리즘은 다음과 같다

코드를 보고 복잡도를 분석해보자.

#include<bits/stdc++.h>
using namespace std;
deque<pair<int,int> > dq;
int main(void){
  ios::sync_with_stdio(false); cin.tie(NULL);
  int n,l; cin>>n>>l;
  for(int i=1;i<=n;i++){
    int x; cin>>x;
    while(!dq.empty() && dq.front().second<=i-l){
      dq.pop_front();
    }
    while(!dq.empty() && dq.back().first>=x){
      dq.pop_back();
    }
    dq.push({x,i});
    cout<<dq.front().first<<" ";
  }
  return 0;
}

코드는 간단하군요… 복잡도를 계산하기 위해 deque에 들어가는 원소의 입장이 되어보겠습니다. 원소는 2가지 일을 수행합니다. deque에 들어가거나, 나가거나. 모든 원소가 deque에 들어가거나 나오기 때문에 복잡도는 O(c*n), 즉 O(n)이 되는군요!