[오늘의 백준] 1920. 수찾기

한지원·2021년 5월 28일
0

1920. 수찾기

문제
N개의 정수 A[1], A[2], …, A[N]이 주어져 있을 때, 이 안에 X라는 정수가 존재하는지 알아내는 프로그램을 작성하시오.


입력
첫째 줄에 자연수 N(1 ≤ N ≤ 100,000)이 주어진다. 다음 줄에는 N개의 정수 A[1], A[2], …, A[N]이 주어진다. 다음 줄에는 M(1 ≤ M ≤ 100,000)이 주어진다. 다음 줄에는 M개의 수들이 주어지는데, 이 수들이 A안에 존재하는지 알아내면 된다. 모든 정수의 범위는 -2³¹ 보다 크거나 같고 2³¹보다 작다.


출력
M개의 줄에 답을 출력한다. 존재하면 1을, 존재하지 않으면 0을 출력한다.

예제 입력

5
4 1 5 2 3
5
1 3 7 9 5

예제 출력

1
1
0
0
1

그냥 리스트로 받아서 선형 탐색으로 풀면 시간초과가 뜬다. list형의 containment 연산의 시간 복잡도는 O(n)이기 때문에 containment연산의 시간 복잡도가 O(1)인 set자료형을 사용해 풀거나 이분탐색을 이용해 문제를 풀어야한다.
참고1-파이썬 자료형 별 기본 연산자의 시간 복잡도1
참고2-파이썬 자료형 별 기본 연산자의 시간 복잡도2

set자료형을 이용한 풀이

import sys

a = int(input())
n = set(sys.stdin.readline().split())
b = int(input())
m = sys.stdin.readline().split()
for i in m:
	print('1') if i in n else print('0')

이분 탐색을 이용한 풀이

import sys

def binary_search(i, n, start, end):
    if start > end:
        return (0)
    mid = (start + end) // 2
    if i == n[mid]:
        return (1)
    elif i < n[mid]:
        return (binary_search(i, n, start, mid-1))
    else:
        return (binary_search(i, n, mid+1, end))
    
a = int(input())
n = sorted(map(int, sys.stdin.readline().split()))
b = int(input())
m = map(int, sys.stdin.readline().split())
start = 0
end = len(n) - 1
for i in m:
    print(binary_search(i, n, start, end))


위에 있는게 이진 탐색을 이용해서 푼 것인데 함수가 반복적으로 호출되고 sort과정도 더해져 있어 시간이 더 오래걸린 것 같다.

다른 사람이 푼 코드를 보니 딕셔너리 자료형을 이용해 풀기도 했다. 딕셔너리 변수를 선언해주고 자연수 N각각과 1을 키-값 쌍으로 추가한 뒤 M의 숫자 하나하나를 돌며 get함수로 딕셔너리에 해당 키가 있는지 확인한다. 딕셔너리 자료형의 get함수 시간복잡도도 set과 마찬가지로 O(1)이기 때문에 시간 초과가 뜨지 않는다.


오랜만에 파이썬으로 문제를 풀어봤다. 42서울에서 씨언어만 이용해서 프로젝트를 하고, js스터디를 시작해서 파이썬으로 코딩을 진짜 정말 오랜만에 한다 ㅋ 그래서인지 안그래도 뜨문뜨문 알고있던 문법들이 생각이 안났다..ㅋ map함수, sort와 sorted의 차이, 각 자료형 별 연산들 다시한번 정리하고 머릿속에서 언어들 짬뽕 안되게 조심 ㅋ

0개의 댓글