본문 바로가기

문돌이 존버/프로그래밍 스터디

(프로그래머스 스택/큐 문제 풀이) 주식가격

반응형

스택/큐(Stack/Queue)

주식가격

문제 설명
초 단위로 기록된 주식가격이 담긴 배열 prices가 매개변수로 주어질 때, 가격이 떨어지지 않은 기간은 몇 초인지를 return 하도록 solution 함수를 완성하세요.

제한사항
prices의 각 가격은 1 이상 10,000 이하인 자연수입니다.
prices의 길이는 2 이상 100,000 이하입니다.

입출력 예
prices                      return
[1, 2, 3, 2, 3]         [4, 3, 1, 1, 0]

입출력 예 설명
1초 시점의 ₩1은 끝까지 가격이 떨어지지 않았습니다.
2초 시점의 ₩2은 끝까지 가격이 떨어지지 않았습니다.
3초 시점의 ₩3은 1초뒤에 가격이 떨어집니다. 따라서 1초간 가격이 떨어지지 않은 것으로 봅니다.
4초 시점의 ₩2은 1초간 가격이 떨어지지 않았습니다.
5초 시점의 ₩3은 0초간 가격이 떨어지지 않았습니다.
def solution(prices):
    answer = [0] * len(prices)
    price_stack = []
    
    for i, price in enumerate(prices):
        while price_stack and price < prices[price_stack[-1]]:
            j = price_stack.pop()
            answer[j] = i - j
        price_stack.append(i)
    
    while price_stack:
        j = price_stack.pop()
        answer[j] = len(prices) - 1 - j
    return answer

문제를 보고 딱 들었던 생각은 prices의 인덱스를 따로 뽑아서 가격이 몇 초 유지되었는지 판단해야겠다는 것이다. 그런데 해시 문제가 아닌 스택/큐 문제기 때문에 딕셔너리는 아닐 것이고, 그렇다면 어떻게 해야하는지 고민하다 결국 떠올리지 못했다.

해결 방법은 바로 prices와 길이가 똑같은 리스트를 만들고 인덱스에 맞춰서 가격이 몇 초 유지되었는지 정보를 기입하는 것이다. 이를 위해선 prices를 순환할 때 인덱스를 뽑아오도록 enumerate 함수를 사용해야 한다.

그리고 핵심은 새로운 price가 들어올 때 기존 price보다 크다면 stack에 추가해주고, 작다면 stack.pop()을 통해 가격이 유지된 시간을 기록한다. 그리고 끝까지 남아 있는 가격에 대해선 별도의 반복문 작업을 거쳐 시간을 기록해준다.

코드만 봐서는 이해가 안될 수 있으니 아래 과정을 살펴보자.

prices의 원소 2가 들어오는 순간 price stack에서 pop()이 호출되면서 answer[2]는 1초로 업데이트되었다.

while문을 통해 price stack의 남은 원소에 대해서도 유지된 시간을 구하면 최종적으로 아래와 같아진다.

다른 코드를 보면 brute force나 deque 방식으로도 풀었지만 시간 복잡도가 $O(N^2)$가 되며, 위의 코드로 하면 $O(N)$이 보장된다는 점에서 best가 아닐까 싶다.

728x90
반응형