문제 링크 : https://www.acmicpc.net/problem/11003
문제 분석
1. 정렬을 이용한 문제해결
일정 범위 안에서 최소값을 구하는 문제이므로 "슬라이딩 윈도우" 방식과 "정렬"을 통해 답을 추리면 결과를 얻을 수 있으나, 정렬 알고리즘의 시간 복잡도는 O(nlogn) 이므로 문제에 효율적이지 못하다.
( 문제 상황에서 시간 복잡도는 O(nlogn) 정렬 알고리즘을 포함하면 O((N-L+1) * L log L) 이 되는데 이는 모든 슬라이드에서 정렬을 하여 답을 구하는 경우이다. 따라서, 이 문제를 효율적으로 해결하기 위해서는 정렬을 사용하지 않고, 덱(deque)과 같은 자료구조를 활용하여 O(N)의 시간 복잡도로 해결하는 방법이 좋다.)
정렬 알고리즘 중 비교 기반 정렬 알고리즘은 n 개의 원소를 정렬하는데 O(nlogn)의 시간이 소요된다.
2. 덱(deque) 이용한 문제해결
덱(Deque, Double-ended Queue)은 양쪽 끝에서 삽입과 삭제가 가능한 자료구조이다.
큐(Queue)와 비슷하지만,
- 앞에서도(push front) 삽입/삭제 가능
- 뒤에서도(push back) 삽입/삭제 가능
Python에서는 collections.deque 모듈을 사용하면 덱을 쉽게 다룰 수 있다.
1. 덱의 맨 앞 요소는 항상 최솟 값.
2. 덱에 값을 추가할 때 덱의 맨 뒤의 요소와 비교, 맨 뒤 요소가 클 경우 맨 뒤 요소를 제거
3. 덱의 윈도우 범위를 벗어나는 맨 앞 원소 제거
덱의 맨 앞 요소는 항상 현재 슬라이딩 윈도우 내의 최솟값을 나타내며, O(N) 시간 복잡도로 효율적으로 계산하는 알고리즘이다.
코드
from collections import deque
N, L = map(int, input().split())
arr = list(map(int, input().split()))
dq = deque()
result = []
for i in range(N):
while dq and dq[-1][0] > arr[i]: #덱의 맨 뒤 요소가 현재 배열의 원소 보다 크다면 제거
dq.pop()
dq.append((arr[i], i)) #튜플 (인덱스, 값)
if dq[0][1] <= i - L: #덱의 맨 앞 원소의 인덱스, 윈도우 범위를 벗어난다면 제거
dq.popleft()
print(dq[0][0], end=" ")
'코딩테스트' 카테고리의 다른 글
좋다(백준 1253) (0) | 2025.02.18 |
---|---|
나머지 합 구하기(백준 10986) (0) | 2025.02.13 |
빅오 표기법(big-O notation) 정복하기 (1) | 2025.02.10 |