[백준 17298][파이썬] 오큰수

2023. 3. 31. 12:00·백준 알고리즘/자료구조
728x90

https://www.acmicpc.net/problem/17298

 

17298번: 오큰수

첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000,000)이 주어진다. 둘째 줄에 수열 A의 원소 A1, A2, ..., AN (1 ≤ Ai ≤ 1,000,000)이 주어진다.

www.acmicpc.net

우선 문제를 봤을 때 가장 먼저 생각나는 알고리즘은 수열의 모든 값을 조사하는데 각각의 수열마다 자신 다음 값부터 끝까지 자신보다 큰 값이 나올 때까지 찾는 방법이다.

 

9 8 7 6 ... 과 같이 내림차순으로 정렬된 수열이 최악의 경우인데 이럴 경우 1부터 n까지 더한 횟수를 반복해야 한다.

 

즉 시간 복잡도가 O(N^2)이 된다.

 

n의 최대값이 1,000,000이고 파이썬은 1초에 1억번 정도의 연산을 할 수 있다는 점을 고려하면 이 방법은 시간 초과가 발생한다.

 

이 시간을 줄이기 위해서는 최소 힙을 사용해야 한다.

 

예제 입력 2번을 보자.

 

우선 수열의 첫 번째 값부터 조사를 시작한다.

 

1.

첫 번째 값은 무조건 최소 힙에 넣는다. (편의상 힙의 모양을 오름차순으로 정렬된 리스트로 표현하겠다.)

 

heap : [ 9 ] 

 

2.

최소 힙에서 가장 작은 값(temp라고 표현하겠다.)을 꺼내서 두 번째 값 (arr[2] 라고 표현하겠다.)과 비교한다.

 

heap : [ ]

temp = 9, arr[2] = 5

 

temp가 arr[2]보다 크다. 이럴 경우 다시 heap에 temp를 집어넣는다.

 

arr[2] 값도 heap에 넣는다.

 

heap : [ 5, 9 ]

 

3.

최소 힙에서 가장 작은 값(temp)을 꺼내서 세 번째 값  (arr[3]) 과 비교한다.

 

heap : [ 9 ]

temp : 5, arr[3] = 4

 

temp가 arr[3]보다 크다. 이럴 경우 다시 heap에 temp를 집어넣는다.

 

arr[3] 값도 heap에 넣는다.

 

heap : [ 4, 5, 9 ]

 

4.

최소 힙에서 가장 작은 값(temp)을 꺼내서 네 번째 값  (arr[4]) 과 비교한다.

heap : [ 5, 9 ]

temp = 4, arr[4] = 8

 

드디어 temp가 arr[4]보다 작다. 이럴 경우 temp에 해당하는 곳의 오큰수는 arr[4]가 된다.

 

temp가 arr[4]보다 작을 경우 heap에서 한 번 더 가장 작은 값을 꺼낸다.

 

오큰수가 arr[4]인 값이 있을 수도 있기 때문이다.

 

heap : [ 9 ]

temp = 5, arr[4] = 8

 

또 temp가 arr[4]보다 작다. temp에 해당하는 곳의 오큰수는 arr[4]가 된다.

 

한 번 더 꺼낸다.

 

heap : [  ]

temp = 9, arr[4] = 8

 

temp가 arr[3]보다 크다. 이럴 경우 다시 heap에 temp를 집어넣는다.

 

heap : [ 9 ]

 

이제 모든 수열의 값을 조사하였다.

 

아직도 heap에 남아있는 값이 있다면 오큰수가 존재하지 않는 것이다.

 

<전체 코드>

import sys
from collections import deque
import heapq
input=sys.stdin.readline
n=int(input())
arr=list(map(int, input().split()))
heap=[(arr[0], 0)] #첫 번째는 값 두 번째는 인덱스
res=[-1]*n #각각의 인덱스에 대한 오큰수 값
for i in range(1, n):
    while True:
        temp=heapq.heappop(heap) #가장 작은 값 꺼냄
        if temp[0]<arr[i]: #꺼낸 값이 현재 위치보다 작으면
            res[temp[1]]=arr[i] #오큰수 저장
        else:
            heapq.heappush(heap, temp) #꺼낸 값이 크면 다시 최소 힙에 넣음
            break
        if len(heap)==0:
            break
    
    heapq.heappush(heap, (arr[i], i)) #최소 힙에 넣기
for i in res:
    print(i, end=' ')
728x90

'백준 알고리즘 > 자료구조' 카테고리의 다른 글

[백준 2042][파이썬] 구간 합 구하기(펜윅 트리)  (0) 2023.04.26
'백준 알고리즘/자료구조' 카테고리의 다른 글
  • [백준 2042][파이썬] 구간 합 구하기(펜윅 트리)
웅대
웅대
알고리즘과 백엔드를 중심으로 열심히 공부 중입니다! 같이 소통하며 공부해요!
    250x250
  • 웅대
    웅대 개발 블로그
    웅대
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 백준 알고리즘
        • dp
        • 문자열
        • 정렬
        • 스택
        • 브루트 포스
        • 이진 탐색
        • 정리
        • 우선순위 큐
        • 자료구조
        • 그래프
        • 기타
        • 그리디
      • 컴퓨터 언어
        • Kotlin
        • Python
        • C#
      • 공부
        • Database
        • Android Studio
        • Algorithm
        • 컴퓨터 구조론
        • Spring
        • lombok
        • AWS
        • Network
        • OS
        • Git & GitHub
        • AI
        • Computer Vision
        • 보안
        • Nginx
        • 프론트
        • express
        • GCP
        • grokking concurrency
        • DevOps
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Merge
    influxDB CLI
    Vector Store
    openvidu 배포
    RNN
    스택
    푸쉬 알람
    스프링 OAuth2
    다익스트라
    bfs
    ChatPromptTemplate
    ci/cd
    nn.RNN
    binary search
    code tree
    AWS Lambda
    embedding
    codetree
    parametric search
    파이썬
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
웅대
[백준 17298][파이썬] 오큰수
상단으로

티스토리툴바