1. 문제 요약
https://www.acmicpc.net/problem/2493
각 탑은 왼쪽 방향으로 신호를 보낸다.
이때 자신보다 높은 탑 중에서 가장 가까운 탑이 신호를 받는다.
→ 각 탑마다 “왼쪽에서 가장 가까운 높은 탑의 위치”를 구하는 문제
2. 처음 접근 (완전탐색)
처음에는 단순하게 생각했다.
“각 탑마다 왼쪽을 쭉 탐색하면서 처음 만나는 큰 탑 찾으면 되겠네?”
그래서 구현한 코드는 다음과 같다.
import sys
input = sys.stdin.readline
n = int(input())
top = list(map(int, input().split()))
answer = [0] * n
for where in range(n - 1, -1, -1):
height = top[where]
for index in range(where - 1, -1, -1):
if top[index] >= height:
answer[where] = index + 1
break
print(*answer)
3. 문제점
이 방식은 시간복잡도 O(n²) 이다.
- 각 탑마다 왼쪽을 다시 탐색
- 최악의 경우 거의 전체를 매번 탐색
→ 입력이 커지면 바로 시간초과
고민 포인트
여기서 의문이 들었다.
“이미 한 번 본 탑을 또 다시 보는 게 비효율적인데…
이걸 줄일 방법이 없을까?”
4. 핵심 아이디어 (단조 스택)
핵심은 하나였다.
→ “쓸모 없는 탑을 미리 제거하자”
어떤 탑이 쓸모 없을까?
→ 현재 탑보다 작은 탑
이유:
- 현재 탑보다 작으면
- 앞으로 등장하는 어떤 탑에게도
- 더 큰 탑보다 먼저 선택될 일이 없음
→ 즉, 미래에도 절대 정답이 될 수 없음
5. 개선된 풀이
import sys
input = sys.stdin.readline
n = int(input())
top = list(map(int, input().split()))
answer = [0] * n
stack = [] # (인덱스, 높이)
for i in range(n):
while stack and stack[-1][1] < top[i]:
stack.pop()
if stack:
answer[i] = stack[-1][0] + 1
stack.append((i, top[i]))
print(*answer)
6. 동작 원리
1) 작은 탑 제거
while stack and stack[-1][1] < top[i]:
stack.pop()
- 현재 탑보다 작은 탑은 전부 제거
- 이유: 앞으로도 절대 필요 없음
2) 정답 찾기
if stack:
answer[i] = stack[-1][0] + 1
- 스택에는 “나보다 큰 탑들만 남아 있음”
- 그 중 가장 가까운 건 stack의 top
3) 현재 탑 추가
stack.append((i, top[i]))
→ 이후 탑들을 위한 후보로 저장
7. 시간복잡도 비교
방식시간복잡도
| 완전탐색 | O(n²) |
| 단조 스택 | O(n) |
→ 각 원소는 최대 1번 push / 1번 pop
'코딩테스트' 카테고리의 다른 글
| [백준] 6198번 - 옥상 정원 꾸미기 (0) | 2026.04.01 |
|---|---|
| [백준] 18258번 - 카드2 (1) | 2026.03.31 |
| [백준] 20166번 - 문자열 지옥에 빠진 호석 (3) | 2026.03.26 |
| [백준] 19583번 - 싸이버개강총회 (0) | 2026.03.25 |
| [백준] 16165번 - 걸그룹 마스터 준석이 (0) | 2026.03.24 |