문제: https://www.acmicpc.net/problem/1874
사용 알고리즘: 스택
입력
첫 줄에 n (1 <= n <= 100,000)
둘째 줄부터 n 개의 줄에는 수열을 이루는 1 이상 n 이하의 정수가 하나씩 순서대로 출력됨. (같은 정수 2번 나옴x)
1 부터 n 까지의 숫자를 스택에 넣고 빼면서 입력으로 주어진 수열을 만드는 문제
단, 스택에 숫자를 넣을 때는 무조건 오름차순으로 넣어야 함 -> 1 부터 n 까지 차례로 넣어야 함
1. 스택에 숫자를 넣고 빼면서 주어진 수열을 만들 수 있는 경우
- 스택에 숫자를 넣을 때는 '+' 출력
- 스택에서 숫자를 뺄 때는 '-' 출력
2. 스택에 숫자를 넣고 빼면서 주어진 수열을 만들 수 없는 경우에는 'NO' 출력
수열 만들기
파이썬은 스택 자료구조를 제공하지 않음! -> 만들어서 사용할 수도 있지만 귀찮기 때문에 deque 를 이용함
makeSequence 라는 함수를 만들어서 스택에 숫자를 넣었다가 빼면서 수열을 만듦
스택에는 오름차순으로 숫자를 넣어야하기 때문 for 문을 돌려 i 를 스택에 넣어줌
숫자를 집어넣고 나면 while 문을 돌면서 스택에 제일 위에 있는 수와 가리키는 배열의 수가 같지 않을 때까지 pop
stack = deque()
arrIndex = 0
result = [] # + - 를 넣을 배열
def makeSequence(s, arrIndex):
for i in range(1, n+1):
stack.append(i)
result.append('+')
# 스택의 맨 위 숫자와 가르키는 배열의 숫자가 같은 경우
while len(stack) != 0 and stack[-1] == arr[arrIndex]:
stack.pop()
result.append('-')
arrIndex += 1
# 수열을 만들 수 없는 경우 0, 수열을 만들 수 있는 경우 1
return 0 if len(stack) != 0 else 1
전체 코드
import sys
from collections import deque
input = sys.stdin.readline
# 입력
n = int(input())
arr = []
for _ in range(n):
arr.append(int(input()))
stack = deque()
arrIndex = 0
result = [] # + - 를 넣을 배열
def makeSequence(s, arrIndex):
for i in range(1, n+1):
stack.append(i)
result.append('+')
# 스택의 맨 위 숫자와 가르키는 배열의 숫자가 같은 경우
while len(stack) != 0 and stack[-1] == arr[arrIndex]:
stack.pop()
result.append('-')
arrIndex += 1
# 수열을 만들 수 없는 경우 0, 수열을 만들 수 있는 경우 1
return 0 if len(stack) != 0 else 1
# 리턴 값이 1인 경우 result 요소들 출력
# 리턴 값이 0인 경우 'NO' 출력
if makeSequence(stack, arrIndex):
for x in result:
print(x)
else:
print('NO')
시간 복잡도 계산
n = int(input()) # O(1)
arr = []
for _ in range(n): # O(n)
arr.append(int(input()))
# 입력 시간 복잡도: O(n)
stack = deque()
arrIndex = 0
result = []
def makeSequence(s, arrIndex):
for i in range(1, n+1):
stack.append(i)
result.append('+')
while len(stack) != 0 and stack[-1] == arr[arrIndex]:
stack.pop()
result.append('-')
arrIndex += 1
return 0 if len(stack) != 0 else 1
# makeSequence 시간 복잡도: O(n)
- 일단 for 문을 n 번 돈다. -> O(n)
- while 루푸는 모든 숫자를 스택에서 제거해야 하므로, 전체적으로 최대 n 번 반복될 수 있다. 스택의 각 숫자는 무조건 스택에서 한 번씩 제거되므로! -> O(n)
총 시간 복잡도는 ?
O(n) + O(n) = O(n)
참고로 append 와 pop 의 시간 복잡도는 O(1) 인 상수 시간의 시간 복잡도를 가진다.
(그냥 스택의 마지막에 추가만 해주면 되므로)
if makeSequence(stack, arrIndex):
for x in result:
print(x)
else:
print('NO')
# 출력 시간 복잡도: 최대 O(2n) = O(n), 최소 O(1)
- 수열을 만들 수 있는 경우가 O(n)
- 수열을 만들 수 없는 경우가 O(1)
모든 숫자는 스택에 들어갔다가 나오게 된다. 그러므로 result 의 길이는 n 의 2 배가 된다. -> O(2n) = O(n)
수열을 만들 수 없는 경우는 'NO' 만 출력하면 되므로 -> O(1)
그래서 총 시간 복잡도를 구해본다면 O(n) + O(n) + O(n) = O(3n) 이지만 상수는 무시하므로 O(n) 시간의 시간 복잡도룰 가지게 된다.
- 입력: O(n)
- makeSequence: O(n)
- 출력: O(n)
'백준' 카테고리의 다른 글
[백준/Python] 18258 큐2 (0) | 2024.07.30 |
---|---|
[백준/Python] 12789 도키도키 간식드리미 (0) | 2024.07.28 |
[백준/Python] 17413 단어 뒤집기 2 (0) | 2024.07.25 |
[백준/Python] 10773 제로 (0) | 2024.07.24 |
[백준/Python] 1260 DFS 와 BFS (1) | 2024.07.18 |