숫자 카드는 정수 하나가 적혀져 있는 카드이다. 상근이는 숫자 카드 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, 2, 2, 4, 4, 5, 6, 6, 9] 이고, 찾으려는 숫자가 4라고 가정해보자.
4가 제일 처음 나오는 인덱스는 3이 될 것이고, 4가 아닌 다음 숫자의 첫 인덱스는 6이 될 것이다. 따라서 찾으려는 4의 개수는 이 둘의 차이인 2이다.
찾으려는 숫자의 첫 인덱스는 minBinarySearch() 메서드에서 구현했고, 다음 숫자의 첫 인덱스는 maxBinarySearch() 메서드에서 구현했다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Baekjoon_10816 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
int[] arr = new int[n];
StringTokenizer st = new StringTokenizer(br.readLine());
for (int i = 0; i < n; i++) {
arr[i] = Integer.parseInt(st.nextToken());
}
int m = Integer.parseInt(br.readLine());
int[] arr2 = new int[m];
st = new StringTokenizer(br.readLine());
for (int i = 0; i < m; i++) {
arr2[i] = Integer.parseInt(st.nextToken());
}
Arrays.sort(arr);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < m; i++) {
int max = maxBinarySearch(arr, n, arr2[i]);
int min = minBinarySearch(arr, n, arr2[i]);
int result = max - min;
sb.append(result + " ");
}
System.out.println(sb);
}
public static int minBinarySearch(int[] arr, int n, int find) {
int left = 0;
int right = n;
while (left < right) {
int mid = (left + right) / 2;
if (arr[mid] >= find) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
}
public static int maxBinarySearch(int[] arr, int n, int find) {
int left = 0;
int right = n;
while (left < right) {
int mid = (left + right) / 2;
if (arr[mid] > find) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
}
}