🎯 1. μŠ€νƒκ³Ό 큐 κΈ°λ³Έ κ°œλ… ⭐⭐⭐

μŠ€νƒ (Stack) - LIFO (Last In First Out)

# μŠ€νƒ: λ‚˜μ€‘μ— λ“€μ–΄κ°„ 것이 λ¨Όμ € λ‚˜μ˜΄ (μ ‘μ‹œ μŒ“κΈ°)
#
#     β”Œβ”€β”€β”€β”
#     β”‚ 3 β”‚ ← top (κ°€μž₯ λ‚˜μ€‘μ— λ“€μ–΄μ˜΄)
#     β”œβ”€β”€β”€β”€
#     β”‚ 2 β”‚
#     β”œβ”€β”€β”€β”€
#     β”‚ 1 β”‚ ← bottom (κ°€μž₯ λ¨Όμ € λ“€μ–΄μ˜΄)
#     β””β”€β”€β”€β”˜
#
# push(3) β†’ pop() β†’ 3이 λ‚˜μ˜΄

# μŠ€νƒ μ—°μ‚°
# - push: 맨 μœ„μ— μΆ”κ°€
# - pop: 맨 μœ„μ—μ„œ 제거
# - peek/top: 맨 μœ„ μš”μ†Œ 확인 (제거 μ•ˆ 함)

큐 (Queue) - FIFO (First In First Out)

# 큐: λ¨Όμ € λ“€μ–΄κ°„ 것이 λ¨Όμ € λ‚˜μ˜΄ (μ€„μ„œκΈ°)
#
#  front                    rear
#    ↓                        ↓
#  β”Œβ”€β”€β”€β”¬β”€β”€β”€β”¬β”€β”€β”€β”¬β”€β”€β”€β”
#  β”‚ 1 β”‚ 2 β”‚ 3 β”‚ 4 β”‚
#  β””β”€β”€β”€β”΄β”€β”€β”€β”΄β”€β”€β”€β”΄β”€β”€β”€β”˜
#
# enqueue(4) β†’ dequeue() β†’ 1이 λ‚˜μ˜΄

# 큐 μ—°μ‚°
# - enqueue: 뒀에 μΆ”κ°€
# - dequeue: μ•žμ—μ„œ 제거
# - front: 맨 μ•ž μš”μ†Œ 확인 (제거 μ•ˆ 함)

리슀트둜 μŠ€νƒ/큐 κ΅¬ν˜„μ˜ 문제

# μŠ€νƒ: 리슀트둜 κ΅¬ν˜„ κ°€λŠ₯ (O(1))
stack = []
stack.append(1)      # push - O(1) βœ…
stack.append(2)
stack.pop()          # pop - O(1) βœ…

# 큐: 리슀트둜 κ΅¬ν˜„ν•˜λ©΄ 느림!
queue = []
queue.append(1)      # enqueue - O(1) βœ…
queue.append(2)
queue.pop(0)         # dequeue - O(n) ❌ 느림!

# μ™œ? pop(0)은 μ•ž μš”μ†Œ 제거 ν›„ λͺ¨λ“  μš”μ†Œλ₯Ό ν•œ μΉΈμ”© μ•žμœΌλ‘œ 이동!
# [1, 2, 3, 4, 5]
# pop(0) β†’ [2, 3, 4, 5]  # λͺ¨λ“  μš”μ†Œ 이동 O(n)

🎯 2. deque κΈ°λ³Έ μ‚¬μš©λ²• ⭐⭐⭐

dequeλž€?

from collections import deque

# deque (Double-Ended Queue)
# - μ–‘μͺ½ λμ—μ„œ O(1)둜 μΆ”κ°€/μ‚­μ œ κ°€λŠ₯
# - μŠ€νƒκ³Ό 큐λ₯Ό λͺ¨λ‘ 효율적으둜 κ΅¬ν˜„ κ°€λŠ₯

dq = deque([1, 2, 3, 4, 5])

μ–‘μͺ½ 끝 μΆ”κ°€/제거 (핡심!) ⭐⭐⭐

from collections import deque

dq = deque([1, 2, 3])

# 였λ₯Έμͺ½ 끝 μΆ”κ°€/제거
dq.append(4)         # deque([1, 2, 3, 4]) - O(1)
dq.pop()             # 4 λ°˜ν™˜ - O(1)

# μ™Όμͺ½ 끝 μΆ”κ°€/제거
dq.appendleft(0)     # deque([0, 1, 2, 3]) - O(1) βœ…
dq.popleft()         # 0 λ°˜ν™˜ - O(1) βœ…

# 이게 λ¦¬μŠ€νŠΈμ™€μ˜ 핡심 차이!
# 리슀트의 pop(0)은 O(n)μ΄μ§€λ§Œ
# deque의 popleft()λŠ” O(1)!

μ‹œκ°„λ³΅μž‘λ„ 비ꡐ

μ—°μ‚° 리슀트 deque
append (끝) O(1) O(1)
appendleft (μ•ž) O(n) ❌ O(1) βœ…
pop (끝) O(1) O(1)
popleft (μ•ž) O(n) ❌ O(1) βœ…
인덱슀 μ ‘κ·Ό O(1) βœ… O(n) ❌

κΈ°λ³Έ λ©”μ„œλ“œ

from collections import deque

dq = deque([1, 2, 3, 4, 5])

# μΆ”κ°€
dq.append(6)         # 였λ₯Έμͺ½ 끝: deque([1, 2, 3, 4, 5, 6])
dq.appendleft(0)     # μ™Όμͺ½ 끝: deque([0, 1, 2, 3, 4, 5, 6])

# μ—¬λŸ¬ 개 μΆ”κ°€
dq.extend([7, 8])    # deque([0, 1, 2, 3, 4, 5, 6, 7, 8])
dq.extendleft([-2, -1])  # deque([-1, -2, 0, 1, ...]) (μ—­μˆœ 주의!)

# 제거
dq.pop()             # 8 λ°˜ν™˜
dq.popleft()         # -1 λ°˜ν™˜

# νšŒμ „
dq = deque([1, 2, 3, 4, 5])
dq.rotate(1)         # deque([5, 1, 2, 3, 4]) (였λ₯Έμͺ½μœΌλ‘œ)
dq.rotate(-1)        # deque([1, 2, 3, 4, 5]) (μ™Όμͺ½μœΌλ‘œ)

# 기타
len(dq)              # 길이
dq[0]                # 첫 번째 μš”μ†Œ (O(1))
dq[-1]               # λ§ˆμ§€λ§‰ μš”μ†Œ (O(1))
# dq[2]              # 쀑간 μš”μ†Œ (O(n) - 느림!)

dq.clear()           # 전체 μ‚­μ œ

🎯 3. μŠ€νƒ κ΅¬ν˜„ 및 ν™œμš© ⭐⭐⭐

deque둜 μŠ€νƒ κ΅¬ν˜„