"단조 스택은 쓸모가 없어지는 순간 그걸 버려. 다시는 볼 일이 없으니까. 그 냉정한 망각이 O(n²)짜리 '앞을 내다보기'를 O(n) 한 번으로 바꿔."
이게 푸는 문제
이런 문제를 생각해 봐. 배열의 각 원소마다 오른쪽에서 처음 만나는 더 큰 원소("next greater element")를 찾는 거야. 떠오르는 방법은 원소마다 오른쪽으로 더 큰 게 나올 때까지 훑는 건데, 그러면 O(n²)라 데이터가 많으면 못 써. 단조 스택은 이걸 통째로 O(n)에 풀어. 이 퀘스트에서 손꼽히게 통쾌한 기법이야.
아이디어: 스택을 정렬 상태로 유지
단조 스택은 원소를 정렬된 상태로 유지해. 예를 들면 바닥에서 위로 갈수록 작아지게. 유지하는 방법은 새 값을 push하기 전에 순서를 어기는 원소를 전부 pop하는 것이야. next greater가 여기서 나와. 왼쪽에서 오른쪽으로 걸어가면서, 새 값을 넣기 전에 스택에 있는 그보다 작은 원소를 전부 pop해. 왜냐면 그렇게 pop되는 원소들에게는 바로 이 새 값이 next greater element거든. 한 동작으로 답을 주고 내보낸 거야. 스택에 남아 있는 건 아직 자기 답을 기다리는 것들이고.
안쪽에 pop 반복문이 있는데 왜 O(n²)가 아니라 O(n)일까. 복잡도 트랙에서 쓴 분할 상환 논증 그대로야. 원소 하나가 정확히 한 번 push되고 많아야 한 번 pop되니까 push와 pop을 합쳐도 2n을 안 넘어. 어느 한 단계에서 여러 개를 pop할 수는 있어도 전체를 통틀어 안쪽 반복문이 한 일의 총량은 선형이야. 중첩된 모양이 아니라 총 연산 횟수를 세면 O(n)이 드러나.
문제의 가문
이 모양을 알아보면 문제 한 무리가 통째로 열려. next greater / next smaller element, daily temperatures(더 따뜻한 날까지 며칠 남았나), stock span(직전 며칠 연속으로 더 낮았나), 그리고 저 유명한 히스토그램 최대 직사각형. 전부 신호 하나를 공유해. "각 원소마다 어떤 방향으로 그걸 넘어서는 가장 가까운 원소를 찾아라." 이 말이 들리면 단조 스택을 꺼내.