#스택

프로그래머스 문제 중 스택 분류에 해당하는 풀이를 다룬다. 현재 5개의 풀이가 있다.

스택 학습 가이드

필요한 주제만 펼쳐서 스택의 동작과 활용법을 익힌다.

스택 기본 개념

스택은 가장 나중에 들어온 원소를 가장 먼저 꺼내는 LIFO 자료구조다. 책을 쌓고 위에서부터 꺼내는 모습을 떠올리면 된다.

스택에 A, B, C, D를 순서대로 넣고 가장 위의 D부터 꺼내는 LIFO 동작 그림
새 원소는 위에 넣고, 제거할 때도 가장 위의 원소부터 꺼낸다.
  • push: 스택의 맨 위에 원소 추가
  • pop: 스택의 맨 위 원소 제거 및 반환
  • peek: 제거하지 않고 맨 위 원소 확인
  • empty: 스택에 원소가 남아 있는지 확인

괄호의 짝 확인, 실행 취소, 함수 호출 기록, 역순 처리처럼 가장 최근 상태를 먼저 되돌려야 하는 문제에 맞는다.

Python에서 스택 구현

Python에서는 리스트의 오른쪽 끝을 스택의 top으로 쓰면 `append`와 `pop`을 모두 평균 `O(1)`에 처리할 수 있다.

Python 리스트의 오른쪽 끝을 스택의 top으로 사용하고 append와 pop을 수행하는 그림
리스트의 오른쪽 끝을 top으로 쓰면 원소를 효율적으로 추가하고 제거할 수 있다.
stack = []
stack.append(value)  # push
top = stack[-1]      # peek
value = stack.pop()  # pop

빈 스택에서 `pop`이나 `stack[-1]`을 실행하면 오류가 발생하므로, 제거하거나 확인하기 전에 `stack`이 비어 있지 않은지 검사해야 한다.

단조 스택

단조 스택은 스택 안의 원소가 항상 오름차순 또는 내림차순을 유지하도록 원소를 제거하는 기법이다. 현재 값이 규칙을 깨면 top을 꺼낸 뒤 현재 값을 넣는다.

30, 31, 30, 32를 읽으며 더 큰 32가 단조 스택의 작은 값들을 해결하는 그림
현재 값이 더 크면 top의 작은 값들을 꺼내 다음 큰 값을 찾는 문제를 해결할 수 있다.
  • 다음으로 큰 값 또는 다음으로 작은 값 찾기
  • 각 위치에서 왼쪽이나 오른쪽의 첫 조건 만족 원소 찾기
  • 히스토그램에서 가장 큰 직사각형처럼 경계를 계산하는 문제

각 원소는 스택에 한 번 들어가고 최대 한 번 나오므로, 반복문 안에 `while`이 있어도 전체 시간 복잡도는 보통 `O(n)`이다.

문제 조건별 스택 활용
문제 조건우선 고려할 방법
괄호나 중첩 구조의 짝 확인일반 스택
최근 작업을 되돌리기스택에 상태 저장
다음 큰 값·작은 값 찾기단조 스택
표현식 또는 후위 표기식 계산값 스택, 연산자 스택
인접한 원소를 조건에 따라 제거스택에 결과 후보 유지
자주 하는 실수
  • 빈 스택에서 `pop`이나 top 조회를 실행하는 경우
  • 스택의 top이 아닌 앞쪽 원소를 제거해 LIFO 규칙을 깨는 경우
  • 괄호 문제에서 여는 괄호의 종류와 닫는 괄호의 종류를 비교하지 않는 경우
  • 단조 스택에서 같은 값에 `>`와 `>=` 중 어떤 조건이 필요한지 구분하지 않는 경우
  • 현재 원소를 스택에 넣기 전에 이전 원소를 해결해야 하는 순서를 놓치는 경우

전체 문제 풀이 보기