10816번 문제
숫자 카드는 정수 하나가 적혀져 있는 카드이다. 상근이는 숫자 카드 N개를 가지고 있다. 정수 M개가 주어졌을 때, 이 수가 적혀있는 숫자 카드를 상근이가 몇 개 가지고 있는지 구하는 프로그램을 작성하시오.
입력
첫째 줄에 상근이가 가지고 있는 숫자 카드의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 둘째 줄에는 숫자 카드에 적혀있는 정수가 주어진다. 숫자 카드에 적혀있는 수는 -10,000,000보다 크거나 같고, 10,000,000보다 작거나 같다.
셋째 줄에는 M(1 ≤ M ≤ 500,000)이 주어진다. 넷째 줄에는 상근이가 몇 개 가지고 있는 숫자 카드인지 구해야 할 M개의 정수가 주어지며, 이 수는 공백으로 구분되어져 있다. 이 수도 -10,000,000보다 크거나 같고, 10,000,000보다 작거나 같다.
이진 탐색
이진 탐색을 구현하기 위해서는 위치를 나타내는 변수 3개를 사용한다. 시작점, 끝점, 중간점이다. 찾으려는 데이터와 중간점 위치에 있는 데이터를 반복적으로 비교하고, 탐색 범위를 반씩 줄여가며 데이터를 찾는다.
숫자 카드에 적힐 수 있는 수의 범위가 크기 때문에(-10,000,000 ~ 10,000,000) 시간복잡도가 낮은 이진탐색을 처음에 생각한 코드는 다음과 같다.
# 숫자 카드 2
N = int(input())
cards = list(map(int, input().split()))
M = int(input())
entity = list(map(int, input().split()))
results = [0] * M
cards.sort() #이진탐색을 위해 정렬
def binarysearch(start, end, x):
global cards
while start<=end:
mid = (start+end)//2
if cards[mid] > x :
end = mid - 1
elif cards[mid] < x:
start = mid + 1
elif cards[mid] == x:
return cards.count(x)
return None
for e in entity:
result = binarysearch(0, N-1, e)
if result is not None:
print(result, end=' ')
elif result is None:
print(0, end=' ')
하지만 백준 컴파일러로는 시간초과가 나서 계수정렬을 활용하여 시도했다.
계수 정렬
계수 정렬은 일반적으로 별도의 리스트를 선언하고 그 안에 정렬에 대한 정보를 담는다.
계수 정렬 조건
1. 데이터의 크기 범위가 제한되어 있을 때
2. 데이터가 전부 정수 형태일때
=> 숫자 카드의 범위는 (-10,000,000 ~ 10,000,000)로 고정되어 있기 때문에 Counter를 직접 구현하여 풀어보았다.
# 숫자 카드2
N = int(input())
cards = list(map(int, input().split()))
M = int(input())
entity = list(map(int, input().split()))
count = [0] * M
for i in range(len(entity)):
for c in cards:
if entity[i]==c:
count[i] += 1
cards.remove(c)
for c in count:
print(c, end=' ')
또 시간초과가 발생하였다. 계수 정렬 방식은 일반적으로 가장 큰 데이터와 가장 작은 데이터의 차이가 1,000,000을 넘지 않을때 효과적으로 채택할 수 있는데, 아무래도 숫자 카드의 범위가 넓어서 실패한 것 같다.
따라서 해쉬맵 - 즉 파이썬에서는 딕셔너리 자료형을 사용했다.
해쉬값을 이용하여 자료형에 저장하게 되면, 키값으로 메모리 주소를 바로 구할 수 있기 때문에 조회 속도가 빨라진다.
hash = {}
for c in cards:
if c in hash:
hash[c] += 1
else:
hash[c] = 1
for e in entity:
if e in hash:
print(hash[e], end=' ')
else:
print(0, end=' ')
위 코드로 무사히 통과되었다 !
=== ref ===
해시맵 참고 : https://hongcoding.tistory.com/12
'알고리즘' 카테고리의 다른 글
[백준] 🏅11559번 골드4 Puyo Puyo (파이썬 Python) (0) | 2025.02.28 |
---|---|
[자료구조] 우선순위 큐 (파이썬 heapq 사용법) (1) | 2024.06.14 |
[프로그래머스] lv3. 순위 (파이썬 Python) (1) | 2024.05.30 |
[백준] 🏅1107번 리모콘(파이썬 Python) (2) | 2024.04.18 |
[이코테] 4장 구현 (0) | 2023.06.29 |