Last In First Out
스택이란 가장 마지막에 들어온 데이터가 가장 먼저 빠져나가는 형태의 자료구조 이다.
👉스택 내에서 특정 데이터를 탐색하려면 O(N) 시간이 필요하다.
Python에서는 List로 구현한다.
stack = [] #stack이라는 이름의 list 선언
stack.append(Value) #Value를 삽입 (Push)
stack.pop() #가장 마지막에 Push된 값 삭제 (Pop)
First In First Out
큐란 가장 처음 들어온 데이터가 가장 먼저 빠져나가는 형태의 자료구조 이다.
Python에서는 collections 라이브러리에서 deque를 import하여 사용한다.
👉사실 deque가 큐와 스택의 기능을 모두 포함하는 자료구조이긴 하지만, 스택만 쓸꺼면 대부분 리스트로 구현한다.
from collections import deque
queue = deque([]) #queue라는 이름의 deque 선언
queue.append(Value) #Value를 삽입 (Push)
queue.popleft() #먼저 들어온 값 삭제 (Pop)
👉위에서 말했듯 deque가 앞에서도 뺄 수 있고, 뒤에서도 뺄 수 있기때문에, pop()과 popleft()로 어디서 뺄지 구분해준다.
수열의 크기와 수열이 주어진다.
이때, 수열의 각 원소 중 원소보다 오른쪽에 있고, 해당 원소보다 큰 수중에서도 제일 왼쪽에 있는 수가 오큰수이다.
이런 수가 없을 경우 오큰수는 -1이 될때, 오큰수들을 구하는 문제이다.
처음엔 시간초과를 생각하지 않고, 큐를 이용해서 접근해보았다.
# queue 사용한 코드
import sys
input = sys.stdin.readline
from collections import deque
n = int(input())
arr = list(map(int, input().split()))
def nge(s):
que = deque([])
for i in range(s, n):
if arr[s] < arr[i]:
que.append(arr[i])
if que:
return que.popleft()
else:
return -1
for i in range(n):
print(nge(i), end=' ')
시간초과가 발생한다.
👉for문 안에서 for문을 사용하는 nge함수를 호출했기 때문에, 시간복잡도가 O(n^2)만큼 걸린다.
결국 for문을 줄이는 방법을 찾아야했다.
stack을 이용해서 거꾸로 오큰수를 찾아나간다.
# stack 사용한 코드
import sys
input = sys.stdin.readline
from collections import deque
n = int(input())
stack = list(map(int, input().split()))
NGE = deque([-1])
top = stack[-1]
for i in range(n-1):
temp = stack.pop()
if temp > stack[-1]:
NGE.appendleft(temp)
elif top > stack[-1]:
NGE.appendleft(top)
else:
NGE.appendleft(-1)
top = stack[-1]
for i in NGE:
print(i, end=' ')
이 코드는 오답이다. 맞왜틀?
👉로직이 잘못되었다. 가장 큰 값이 먼저 스택에 들어가버리면 top값을 초기화를 안해주기 때문이다.
완전히 새로운 로직으로 다시풀었다.
전체코드
import sys
input = sys.stdin.readline
n = int(input())
arr = list(map(int, input().split()))
NGE = [-1 for i in range(n)]
stack = [0]
for i in range(1, n):
while stack and arr[stack[-1]] < arr[i]:
NGE[stack.pop()] = arr[i]
stack.append(i)
print(NGE)
처리가 안된 원소만 탐색하는 코드이다.
스택에 처리가 안된 원소를 넣고, 오큰수를 찾고 나면 처리해주는 로직이다.