일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 코딩테스트실력진단
- 플로이드와샬
- 최단경로
- 머신러닝
- 이분탐색
- 스터디
- Python
- 파인튜닝
- Lora
- 판다스
- 코드트리
- speaking
- English
- Study
- 데이터분석
- Generative AI
- DP
- 그래프이론
- 프로그래머스
- Coursera
- bfs/dfs
- peft
- Scaling Laws
- 코딩테스트
- paper review
- 완전탐색
- LLM
- Fine-Tuning
- 알고리즘
- 파이썬
- Today
- Total
생각하는 아져씨
[BOJ] 2075번 - N번째 큰 수 본문
문제
2075번: N번째 큰 수
첫째 줄에 N(1 ≤ N ≤ 1,500)이 주어진다. 다음 N개의 줄에는 각 줄마다 N개의 수가 주어진다. 표에 적힌 수는 -10억보다 크거나 같고, 10억보다 작거나 같은 정수이다.
www.acmicpc.net
🚦 문제 유형
- 자료 구조
- 정렬
- 우선순위 큐
✏️ Solution
파이썬의 heapq 라이브러리를 사용하여 우선순위 큐를 통해 문제를 풀 수 있다.
N이 최대 1500이고 최대 2,250,000개의 값을 가질 수 있는데, 그 중 N번째 큰 수를 찾기위해 순차탐색을 하는 것은 시간초과가 뜰 것이다.
최댓값 또는 최솟값을 찾을 때 힙 자료구조를 활용하면 쉽게 구할 수 있다.
N번째 큰 수를 찾는 방법은 모든 원소를 힙에 넣고 max_heap 구조에서 N번 heapq.heappop()을 하면 될 것이다.
하지만, 이 풀이방법은 정답은 출력하지만 메모리 초과가 발생한다.
따라서 메모리초과를 해결할 수 있는 다른 방법을 생각해야 했다.
메모리 초과 코드는 다음과 같다.
# 메모리 초과
import sys
import heapq
N = int(sys.stdin.readline())
table = []
for _ in range(N):
tmp = list(map(int, sys.stdin.readline().strip().split(' ')))
for i in tmp:
heapq.heappush(table, (-i, i))
for _ in range(N):
N_max = heapq.heappop(table)
print(N_max[1])
파이썬 메모리 초과에 대한 이유를 몇 가지 찾아봤는데 다음과 같은 이유가 있었다.
- 스택 오버플로우
- 배열에 너무 많은 변수를 저장해서
- DFS 같은 재귀 호출을 너무 많이해서
아마 N번째 큰 수 문제는 최대 2,250,000개의 숫자를 힙이 저장해야 하는데 너무 길어서 메모리 초과가 난 것이 아닐까 생각했다.
정확한 이유를 알기 위해서 자료구조와 메모리구조를 다시 공부해야겠다.
따라서 이 문제는 모든 숫자를 힙에 넣는게 아니라 어차피 N번째 큰 수를 찾는 것이기 때문에 힙의 크기가 N을 유지해서 그 중 가장 작은 값을 찾으면 된다.
- 가장 첫째 줄 배열은 힙에 삽입한다.
- 힙의 크기를 일정하게 유지하기 위해 새로운 숫자가 추가될 때 마다 힙에서 가장 작은 값과 비교하고, 새로 추가되는 값이 크다면 힙에서 가장 작은 값을 삭제한 후 새로운 값을 추가한다.
heapq.heappop(table)
heapq.heappush(table, new) - 마지막으로 힙에는 N개의 수가 남게 되므로 가장 작은 수를 반환하면 답을 얻을 수 있다.
import sys
import heapq
N = int(sys.stdin.readline())
table = []
for _ in range(N):
tmp = list(map(int, sys.stdin.readline().strip().split(' ')))
if not table:
for i in tmp:
heapq.heappush(table, i)
else:
for i in tmp:
if table[0] < i: # 힙의 최솟값보다 클 경우,
heapq.heappop(table)
heapq.heappush(table, i)
print(table[0])
⚙️ Review
힙 문제를 처음 풀어봤는데 어쩐지 풀이 방법이 너무 쉽다 했더니 푸는게 다가 아닌 문제였다.
메모리는 생각도 못했는데 메모리 초과가 나와서 당황했다. 파이썬에서 힙을 사용할 수 있는 방법을 복습할 수 있는 문제였다.
시간초과 말고 메모리초과도 생각하면서 풀자
'Study > Algorithm' 카테고리의 다른 글
[BOJ] 11724번 - 연결 요소의 개수 (0) | 2023.02.16 |
---|---|
[BOJ] 1012번 - 유기농 배추 (0) | 2023.02.14 |
[BOJ] 1406번 - 에디터 (0) | 2022.09.17 |
[BOJ] 14888 - 연산자 끼워넣기 (1) | 2022.09.08 |
[BOJ] 2615번 - 오목 (0) | 2022.09.08 |