PS/프로그래머스

주식가격 (lv2)

ForteQook 2022. 7. 26. 16:15

문제 설명

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

제한 사항

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

 참 멀리 돌아서 온 문제이다. 주식의 특정 시점의 가격이 얼만큼 오래동안 그 가격보다 떨어지지 않는지 알아내는 것이 핵심임을 기억하고 다음 차트를 살펴보자.

  위 차트는 예시로 나온 주식 가격 추이를 나타낸 것이다. 시간이 지날 때 마다 그 이전에 기록된 가격들 중 현재 가격보다 낮은 가격들은 카운트를 그만해야 하는데, 이 아이디어 까지는 떠올리는데 성공했으나 그것을 구현하는데 있어 쓸데없는 짓을 하고 말았다...

 우선 문제의 의도 대로 스택으로 접근해서 문제를 살펴보자. 이 방법은 그저 위에서 떠올린 아이디어를 그대로 가져온 것이며, 반복문을 돌며 스택에 계속해서 각 시점을 넣어주고 동시에 그 스택 안에서 현재 시점의 가격보다 같거나 큰 시점들은 전부 꺼내주는 것이다. 이 방법을 처음에 떠올리지 않은것은 아니지만, 나는 그만 "가격이 하락하는 순간"에만 현재 시점과 그 동안의 주식 가격 비교를 해야한다는 착각을 하고야 말았다. 아무튼 따라서 코드는 다음과 같다...

[프로그래머스] 스택/큐 - 주식가격 (Python 풀이) (tistory.com)

 

[프로그래머스] 스택/큐 - 주식가격 (Python 풀이)

programmers.co.kr/learn/courses/30/lessons/42584 코딩테스트 연습 - 주식가격 초 단위로 기록된 주식가격이 담긴 배열 prices가 매개변수로 주어질 때, 가격이 떨어지지 않은 기간은 몇 초인지를 return 하도록.

tngusmiso.tistory.com

def solution(prices):
    # answer = 몇초 후 가격이 떨어지는지 저장하는 배열
    answer = [len(prices)-i-1 for i in range(len(prices))]
    
    # stack = prices의 인덱스를 차례로 담아두는 배열
    stack = [0]
    
    for i in range(1, len(prices)):
        while stack:
            index = stack[-1]
            
            # 주식 가격이 떨어졌다면
            if prices[index] > prices[i]:
                answer[index] = i - index
                stack.pop()
            
            # 떨어지지 않았다면 다음 시점으로 넘어감 (주식 가격이 계속 증가하고 있다는 말)
            else:
                break
        
        # 스택에 추가한다.
        # 다음 시점으로 넘어갔을 때 다시 비교 대상이 될 예정이다.
        stack.append(i)
        
    return answer

 매 시점마다, 그 이전 시점의 가격들이 현 시점 가격보다 같거나 높으면 카운트를 그만둔다는 직관적이고 효율적인 풀이이다. 같은 아이디어로 upper bound를 통해 좀 더 귀찮고 힘들게 (?) 접근할 수 있다. 반복문으로 주어진 prices를 돌면서, 어떤 리스트를 만들어 놓고 그곳에는 현 시점보다 가격이 같거나 낮은 시점들만 남겨놓는것이다.

li = []

def upperBound(target,start,end):
    while start <= end:
        mid = (start+end) // 2
        if li[mid][1] <= target:
            start = mid + 1
        else:
            end = mid - 1
    return start

def solution(prices):
    global li
    li.append((0,prices[0]))
    n = len(prices)
    answer = [0]*n
    for i in range(1,n-1):
        idx = upperBound(prices[i],0,len(li)-1)
        if idx != len(li):
            for elem in li[idx:]:
                answer[elem[0]] = i-elem[0]
            li = li[:idx]
        li.append((i,prices[i]))
    for i,v in li:
        answer[i] = (n-1) - i
    return answer

 

'PS > 프로그래머스' 카테고리의 다른 글

큰 수 만들기 (lv2)  (0) 2022.07.28
무지의 먹방 라이브 (lv4)  (0) 2022.07.27
네트워크 (lv3)  (0) 2022.07.23
프린터 (lv2)  (0) 2022.07.23
기능 개발 (lv2)  (0) 2022.07.23