본문 바로가기
백준

[백준/Python] 1874 스택 수열

by 보먀 2024. 7. 26.
728x90
반응형

문제: 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)
728x90
반응형

'백준' 카테고리의 다른 글

[백준/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