https://www.acmicpc.net/problem/10845
from collections import deque
N = int(input())
dq = deque()
for _ in range(N):
cmd = input()
if cmd[:4] == "push":
dq.append(int(cmd[5:]))
elif cmd == "pop":
print(dq.popleft() if dq else -1)
elif cmd == "size":
print(len(dq))
elif cmd == "empty":
print(0 if dq else 1)
elif cmd == "front":
print(dq[0] if dq else -1)
else:
print(dq[-1] if dq else -1)
deque
을 사용했다.from collections import deque
import sys
input = sys.stdin.readline
N = int(input())
dq = deque()
for _ in range(N):
cmd = input().strip()
if cmd == "front":
print(dq[0] if dq else -1)
elif cmd == "back":
print(dq[-1] if dq else -1)
elif cmd == "pop":
print(dq.popleft() if dq else -1)
elif cmd == "size":
print(len(dq))
elif cmd == "empty":
print(0 if dq else 1)
else:
dq.append(int(cmd[5:]))
풀이 1에서 입력과 조건문의 순서를 개선했다.
input()
을 sys.stdin.readline()
으로 수정했다.push
인지 검사하려면 slicing
을 사용해야 하므로, 가장 마지막 조건으로 옮겼다.cmd[:4]
과 같은 slicing
연산은 매우 빠른 연산으므로 이 정도 변경으로 인한 시간 단축은 극히 미미하다고 한다.)추가적으로, GPT가 dq[0]
, dq[-1]
의 시간 복잡도가 O(n)이라고 하길래 front
, back
함수를 다음과 같이 고쳐서 제출했다.
if cmd == "front":
if dq:
x = dq.popleft()
print(x)
dq.appendleft(x)
else:
print(-1)
elif cmd == "back":
if dq:
x = dq.pop()
print(x)
dq.append(x)
else:
print(-1)
그런데 GeeksforGeeks에서는 O(1)이라고 나와있더라.
또한 Python 공식 문서에서도 양쪽 끝 인덱스 접근은 O(1)을 보장함이 명시돼있다.
양 끝의 요소에 대한 인덱스 접근은 O(1)이지만, 중간 요소에 대한 접근은 O(n)으로 느려진다.
따라서 빠른 임의 접근이 필요하다면 리스트(list)를 사용하는 것이 좋다.
실제로 두 코드를 백준에 제출해본 결과, dq[0], dq[-1]
의 사용 여부와 관계 없이 동일한 시간이 나왔다.
할루시네이션 네 이놈,,!
deque
은 양 끝의 요소 접근에 대해 이점을 가지며, 중간 요소 접근에 대해서는 느리다.deque
는 무적이고 sys.stdin.readline
은 신이다.