https://www.acmicpc.net/problem/2776
2776번: 암기왕
연종이는 엄청난 기억력을 가지고 있다. 그래서 하루 동안 본 정수들을 모두 기억 할 수 있다. 하지만 이를 믿을 수 없는 동규는 그의 기억력을 시험해 보기로 한다. 동규는 연종을 따라 다니며,
www.acmicpc.net
코드설명
이분탐색 문제 혹은 Set을 활용하여 해결할 수 있습니다.
시간복잡도를 확인해보면,
N(1 ≤ N ≤ 1,000,000), M(1 ≤ M ≤ 1,000,000) 으로써 For문을 활용하여 찾을경우 O(N M )의 시간복잡도가 됩니다.
이것에 T의 범위는 나오지않았지만, T까지 고려한다면 O(T N M )이 됩니다.
이분탐색을 활용하여 해결할 경우 시간복잡도는 O(T M log N) 입니다.
Set은 값을 포함하는지 확인하는 시간복잡도가 O(1) 입니다.
이분탐색과 Set을 활용하여 해결해보겠습니다. 시간복잡도가 Set이 더 빠르지만, 두가지 모두 풀어봅니다.
추가로,
출력의 횟수가 M(1 ≤ M ≤ 1,000,000) * T 이므로 Sysout 을 하는것보다는 StringBuilder를 해야만 시간초과가 나지 않습니다.
코드
Hashset을 활용한 코드 ( 시간 1680 ms , 메모리가 285000 KB )
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.*; public class Main { public static int T, N, M; public static HashSet<Integer> hashset = new HashSet<Integer>(); public static StringBuilder sb = new StringBuilder(); public static void main(String[] args) throws IOException{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); T = Integer.parseInt(st.nextToken()); for(int t=0;t<T;t++) { sb = new StringBuilder(); st = new StringTokenizer(br.readLine()); N = Integer.parseInt(st.nextToken()); hashset = new HashSet<>(); st = new StringTokenizer(br.readLine()); for(int i=0;i<N;i++) { hashset.add(Integer.parseInt(st.nextToken())); } st = new StringTokenizer(br.readLine()); M = Integer.parseInt(st.nextToken()); st = new StringTokenizer(br.readLine()); for(int j=0;j<M;j++) { boolean result = hashset.contains(Integer.parseInt(st.nextToken())); sb.append(result ? 1 : 0).append("\n"); } System.out.print(sb); } } }
이분탐색을 활용한 코드 ( 시간 2100ms , 메모리 230000 KB )
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.*; public class Main { public static int T, N, M; public static int[] arr; public static int answer = 0; public static StringBuilder sb = new StringBuilder(); public static void main(String[] args) throws IOException{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); T = Integer.parseInt(st.nextToken()); for(int t=0;t<T;t++) { sb = new StringBuilder(); st = new StringTokenizer(br.readLine()); N = Integer.parseInt(st.nextToken()); arr = new int[N]; st = new StringTokenizer(br.readLine()); for(int i=0;i<N;i++) { arr[i] = Integer.parseInt(st.nextToken()); } Arrays.sort(arr); st = new StringTokenizer(br.readLine()); M = Integer.parseInt(st.nextToken()); st = new StringTokenizer(br.readLine()); for(int j=0;j<M;j++) { binarySearch(Integer.parseInt(st.nextToken())); } System.out.print(sb); } } public static void binarySearch(int target) { int start = 0; int end = N - 1; while(start <= end) { int middle = (start + end) / 2; if(arr[middle] == target) { sb.append('1').append("\n"); // System.out.println("1"); return ; } if(arr[middle] < target) { start = middle + 1; }else { // while(start <= end) 이기에 end를 더 작게만들어줘야함 end = middle - 1; } } sb.append('0').append("\n"); // System.out.println("0"); } }
추가정보
Set의 시간복잡도 add : O(1) contains : O(1) next : o(h/n) h는 테이블 용량 ArrayList의 시간복잡도 add : O(1) remove : O(n) get : O(1) Contains : O(n) iterator.remove : O(n) LinkedList의 시간복잡도 add : O(1) remove : O(1) get : O(n) Contains : O(n) iterator.remove : O(1)
'알고리즘 > binary_search' 카테고리의 다른 글
[백준] 7795 먹을 것인가 먹힐 것인가 - 이분탐색(binary search) JAVA (0) | 2023.08.04 |
---|---|
[백준] 1072 게임 - 파라매트릭 서치(Paramatric Search) JAVA (0) | 2023.08.03 |
[백준] 1477 휴게소 세우기 - 파라매트릭 서치(Paramatric Search) JAVA (0) | 2023.07.31 |
[백준] 2110 공유기 설치 - 파라매트릭 서치(Paramatric Search) JAVA (0) | 2023.07.30 |
[백준] 3079 입국심사 - 파라매트릭 서치(Paramatric Search) JAVA (0) | 2023.07.28 |