숫자 카드는 정수 하나가 적혀져 있는 카드이다. 상근이는 숫자 카드 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보다 작거나 같다.
첫째 줄에 입력으로 주어진 M개의 수에 대해서, 각 수가 적힌 숫자 카드를 상근이가 가지고 있으면 1을, 아니면 0을 공백으로 구분해 출력한다.
5
6 3 2 10 -10
8
10 9 -5 2 3 4 5 -10
1 0 0 1 1 0 0 1
import sys
input = sys.stdin.readline
n = int(input())
nlist = list(map(int, input().split()))
m = int(input())
mlist = list(map(int, input().split()))
for i in mlist:
if i in nlist:
print(1, end=" ")
else:
print(0, end=" ")
for문과 if문을 사용해서 원소를 하나씩 비교하면 되겠다고 생각하여 풀었는데 시간초과가 발생했다. 그래서 백준 하단에 알고리즘 분류 카테고리 목록을 봤는데 이분탐색이 있어서 이분 탐색 방식으로 해결해서 풀었다.
import sys
input = sys.stdin.readline
n = int(input())
nlist = sorted(list(map(int, input().split())))
m = int(input())
mlist = list(map(int, input().split()))
for i in mlist:
low, high = 0, n - 1
check = False
while low <= high:
mid = (low + high) // 2
if nlist[mid] < i:
low = mid + 1
elif nlist[mid] > i:
high = mid - 1
elif nlist[mid] == i:
check = True
break
print(1 if check else 0, end=" ")
이분탐색으로 해결했을 때 시간이 단축 될 줄은 알았지만 시간이 3132ms가 나와 더 빠른 문제풀이 방식이 있을 것 같았고 다른 분들의 코드를 보면서 빠른 코드 위주로 확인을 해보았다.
import sys
input = sys.stdin.readline
n = int(input())
nlist = set(list(map(int, input().split())))
m = int(input())
mlist = list(map(int, input().split()))
for i in mlist:
if i in nlist:
print(1, end=" ")
else:
print(0, end=" ")
다른 사람들의 풀이법을 찾아보다가 시간이 적게 나온 사람들 것을 봤는데 나랑 코드가 set을 썼다는 것을 제외하고 큰 차이가 없었다. 내가 아는 set은 순서와 중복이 없는 자료구조로 알고있는데 카드에는 중복이 없다고 나와있었다. 근데 시간면에서 엄청 큰 차이가 있어 찾아보니 set과 list는 내부적으로 데이터를 저장하고 검색하는 방식이 다르기 때문에, 특히 원소의 존재 여부를 확인할 때 그 차이가 많이 난다고한다.
결론
대규모 데이터에서 원소의 존재 여부만을 빠르게 확인하고 싶다면 set을 사용하자!!
++ 파이썬에서 딕셔너리도 해시테이블 기반
첫번째 코드 : 시간초과
두번째 코드 : 메모리 113108KB 시간 3132ms
세번째 코드 : 메모리 125632KB 시간 612ms
https://www.acmicpc.net/problem/10815 백준 숫자카드 10815번