문제
탑 (https://www.acmicpc.net/problem/2493)
풀이
1. 초기 접근
- 문제조건 해석
- N 이 500,000만 이하로 주어진다고 한다. 즉 O(N) 또는 O(N log N) 안으로 풀어야 한다.
- 선형 탐색 한 번만 가능한 것이다.
- 알고리즘
- 주어진 예제
6 9 5 7 4
에서 앞의 인덱스부터 하나씩 탐색해나간다 했을 때, 현재 인덱스의 값의 올바른 정답이 무엇인지 차근차근 생각해보자. - 맨 왼쪽
6
은 수신하는 곳이 없으니 항상 0일 것이다. 9
도 마찬가지로, '지금까지'9
보다 큰 값이 없었으므로, 값은 0이 된다.5
에서는, 지금까지5
보다 큰 값인9
가 있었다. 따라서 값은 배열에서9
의 인덱스값인 1이 된다.7
도 마찬가지다. 지금까지7
보다 큰 값은9
였으므로, 이 역시 값이 1이 된다.4
에서 한 가지 알게될 수 있는 사실이 있는데, 지금까지 가장 큰 값은9
였으나,9
의 인덱스 값이 아닌,7
의 인덱스 값인 4가 정답이다.- 지금까지의 사실을 생각해보면, 우리는 '지금까지의' 큰 값들을 저장해나가야 한다.
그럼 큰 값이라는건 언제 결정되는가? 현재 값과 비교함으로써 결정된다. - 큰 값들을 순차적으로 저장하고, 가장 마지막에 저장한 큰 값들과 현재 값을 비교한다는 점에서, 우리는 스택을 사용해야함을 알 수 있다.
- 주어진 예제
- 코드
import sys
n = int(input())
arr = list(map(int, sys.stdin.readline().split()))
s, answer = [], []
for idx, height in enumerate(arr, 1):
# 맨 처음 0번째 인덱스의 경우만 따로 처리
if not s:
s.append((idx, height))
answer.append(0)
continue
# 현재 값 height 와, 스택에서의 top값의 height을 비교하여,
# 스택에는 (인덱스, 큰 값) 들을 저장해둔다.
# 1) 즉, 현재 값이 스택 top의 값보다 큰 경우,
# 스택 top값이 현재값 보다 큰 경우일 때까지 계속해서 pop한 후, 현재 값을 넣어주는 것이다.
# 2) 만약 현재 값이 스택 top의 값보다 작은 경우,
# 스택 top에 저장된 인덱스값을 answer[idx]에 저장하면 된다.
while s and s[-1][1] < height:
s.pop()
if s:
answer.append(s[-1][0])
else:
answer.append(0)
s.append((idx, height))
print(*answer)
2. 최소 힙을 이용한 방법 (댓글 참고)
최소 힙을 이용해서, 더 직관적으로 구할 수 있는 것 같다!
아래 댓글을 참고하여 코드를 짰다.
import heapq
n = int(input())
heights = list(map(int, input().split()))
answer = [0]*n
h = [(n-1, heights[-1])]
for i in range(n-2, -1, -1):
height = heights[i]
while len(h) > 0 and height >= h[0][1]:
top_i, top_height = heapq.heappop(h)
answer[top_i] = i+1
heapq.heappush(h, (i, height))
for i, height in h:
answer[i] = 0
print(*answer)
'취업과 기본기 튼튼 > 코딩 테스트 노트' 카테고리의 다른 글
[프로그래머스] 가장 큰 수 (7) | 2019.07.12 |
---|---|
[BOJ] 5430. AC (2) | 2019.04.22 |
[BOJ] 17135. 캐슬 디펜스 (0) | 2019.04.12 |
[BOJ] 14891. 톱니바퀴 (2) | 2019.04.11 |
[BOJ] 12100. 2048 (Easy) (2) | 2019.04.11 |