algorithm/baekjoon
[백준] 17298 오큰수 (파이썬)
support_u
2023. 3. 11. 20:40
문제
17298번: 오큰수
첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000,000)이 주어진다. 둘째 줄에 수열 A의 원소 A1, A2, ..., AN (1 ≤ Ai ≤ 1,000,000)이 주어진다.
www.acmicpc.net
답을 보기 쉬울 것 같길래 도전했다 큰코다쳤다.
문제 자체는 이중for문으로 답 자체는 볼 순 있지만, 시간 복잡도에 걸리기때문에 시간초과가 뜬다.
그래서 stack을 이용했는데, stack 방법에서도 상다히 애를 먹었다
코드
정답 코드
import sys
input = sys.stdin.readline
n = int(input())
li = list(map(int, input().split()))
stack = [0]
answer = [-1] * n
for i in range(1, n):
while stack and li[stack[-1]] < li[i]:
answer[stack.pop()] = li[i]
stack.append(i)
print(*answer)
해설
반례 input 10 9 7 6 5 4 3 2 8 10 1 output 10 8 8 8 8 8 8 10 -1 -1 |
스택에 넣을 것은 인덱스이다. 인덱스 끼리 비교해주어야하기 때문에 stack에 0(9)을 넣고 range는 1(7)에서 시작한다.
스택의 맨 뒤 수보다 li가 클때(2 < 8) stack.pop해준 인덱스에 8을 넣는다.
후 8의 인덱스를 스택에 넣어준다.
실패코드
import sys
input = sys.stdin.readline
n = int(input())
li = list(map(int, input().split()))
stack = []
answer = [-1] * n
for i in range(0, n):
stack.append(li[i])
if len(stack) >= 2 and stack[-2] >= stack[-1]:
continue
else:
for j in range(len(stack)):
if stack[j] < li[i] and answer[j] == -1:
answer[j] = li[i]
print(*answer)
처음부터 스택을 사용할 것이라 예상했지만 스택으로 리스트에 있는 내용을 쪼개서 가져온 다는 생각밖에 못했다.
제출 하면서도 이거 맨 반례와 같은 예시라면 거의 끝에서 가서 다 돌면 이중 for문보다 더 돌아가는거 아닐까하는 의문을 가지고 제출했었다. 그러고 질문방에서 힌트를 얻어서 코드를 고치게 되었다.