본문 바로가기

Algorithm & SQL/Programmers

[Algorithm] [Python] Programmers - 주식가격

Programmers - 주식가격

문제 설명


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

제한사항


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

제출 코드


1차 제출 코드

def solution(prices):
    answer = [[0] for _ in range(len(prices))]
    for i in range(len(prices)):
        cnt = 0
        for j in range(i+1, len(prices)):
            if prices[i] <= prices[j]:
                cnt += 1
        else:
            answer[i] = cnt
    return answer

문제를 정확히 파악하지 못하고 예시 테스트케이스만 보며 작성하였던 코드다.

모든 테스트 케이스에서 무너지고 효율성도 다 무너졌다..

최종 제출 코드

def solution(prices):
    answer = [0] * len(prices)      
    for i in range(len(prices)):
        for j in range(i+1, len(prices)):
            answer[i] += 1
            if prices[i] > prices[j]: break

    return answer

기존 1차 코드에서 주식 가격이 떨어지지 않은 시간을 저장할 cnt 변수를 사용하지 않고 break를 통해 흐름을 제어하였다.


문제 풀이


answer 배열에 루프문 마다 가격이 떨어지지 않은 시간을 구해서 append 하면 시간 초과가 뜬다.

따라서 입력으로 전달받은 prices 중 각각의 원소마다 값이 떨어지지 않은 시간을 저장하기 위한 배열 answer를 모두 0으로 초기화하여 시작한다.

이후, 두 개의 값에 대한 대소비교만 하면 되므로 이중 for 문을 이용하여 값을 비교한다.

outer loop의 변수 i는 비교할 기준의 요소를 정하는 인덱스이다.

inner loop의 변수 j는 i부터 배열의 끝까지 비교할 대상의 인덱스이다.

비교를 할 때, 테스트케이스를 보면 알 수 있듯이 다음 차례에서 바로 가격이 떨어져도 1초를 유지했다고 판정한다.

따라서, 전위연산으로 값을 상승 시켜주고 이후에 if문을 통해 대소비교를 진행하며 값이 떨어졌을 경우 break를 통해 제어한다.


이 문제는 스택/큐 문제로 분류되어 있다.

나만 이렇게 풀었나 싶어 다른 분들의 풀이를 보다보면 스택/큐를 이용한 풀이보다는 이중 for문을 이용한 풀이를 더 많이 살펴볼 수 있었다..


다른 사람의 풀이


from collections import deque

def solution(prices):
    prices = deque(prices)
    answer = []
    len_pr = len(prices)

    while len_pr != 0:
        tmp = prices.popleft()
        len_pr -= 1 
        cnt = 0
        for j in prices:
            if tmp>j:
                cnt+=1
                break
            cnt+= 1
        answer.append(cnt)
    return answer

dequepopleft()를 이용하여 문제를 푸셨다.

pop(0)은 O(N) 복잡도를 갖는 반면 popleft()는 O(1) 복잡도를 갖기 때문에 효과적이다.