프로그래밍/Python

[백준] 11003번 - 최솟값 찾기

뭉이씨 2025. 2. 11. 23:31

문제 링크 : https://www.acmicpc.net/problem/11003

 

문제

N개의 수 A1, A2, ..., AN과 L이 주어진다.

Di = Ai-L+1 ~ Ai 중의 최솟값이라고 할 때, D에 저장된 수를 출력하는 프로그램을 작성하시오. 이때, i ≤ 0 인 Ai는 무시하고 D를 구해야 한다.

 

입력

첫째 줄에 N과 L이 주어진다. (1 ≤ L ≤ N ≤ 5,000,000)

둘째 줄에는 N개의 수 Ai가 주어진다. (-109 ≤ Ai ≤ 109)

 

출력

첫째 줄에 Di를 공백으로 구분하여 순서대로 출력한다.

 

풀이

from collections import deque

N, L = map(int, input().split())
A = list(map(int, input().split()))
num = deque()

for n in range(N):
    while num and num[-1][1] > A[n]:
        num.pop()
    num.append((n+1,A[n]))
    if num[-1][0]-num[0][0] >= L:
        num.popleft()
    print(num[0][1],end=' ')

 

해설

  • 언뜻 보면 단순한 슬라이딩 윈도우 문제처럼 보이지만 시간제한이 있어 최솟값을 추려내는 과정에서 시간을 줄여야한다.
  • 따라서 deque 를 사용했다.
    • deque.pop() : 가장 오른쪽 요소 삭제
    • deque.leftpop() : 가장 왼쪽 요소 삭제
    • deque.append() : 새로운 요소 추가
  • 가장 첫번째 요소와 가장 나중에 들어온 요소의 index 차이가 L 미만이면 최솟값은 유지되므로 가장 나중에 들어온 요소의 값보다 큰 값을 가진 요소들은 모두 삭제해준다.
  • 그 후 새로운 요소 (n+1, A[n])를 추가해준다.
  • 첫번째 요소가 가장 나중에 들어온 요소의 index와 L 이상이면 popleft()로 삭제한다.
  • 원래는 answer 리스트를 생성하여 저장한 뒤, ' '.join(answer) 로 출력하려 했으나 메모리 초과가 떠서 저장하지않고 바로 출력하는 방법으로 바꿨다.