도저히 방법이 생각나지 않아서 무식하게 풀어보았다.
import java.util.Arrays;
class Solution {
public static int[] solution(String[] info, String[] query) {
int[] answer = new int[query.length];
for (int i = 0; i < query.length; i++) {
int cnt = 0;
String[] splited = query[i].split(" and ");
String standardScore = splited[splited.length - 1].split(" ")[1];
splited[splited.length - 1] = splited[splited.length - 1].split(" ")[0];
for (String information : info) {
String[] split = information.split(" ");
if (Integer.parseInt(split[split.length - 1]) >= Integer.parseInt(standardScore)) {
for (int j = 0; j < split.length - 1; j++) {
if(!split[j].equals(splited[j]) && !splited[j].equals("-")) break;
else if (j == 3) cnt++;
}
}
}
answer[i] = cnt;
}
return answer;
}
}
카카오 2021년도 블라인드 기출문제라서 카카오의 풀이를 좀 찾아봤다.
생각하지도 못한 방법을 사용하는 것을 보았는데.. Map에 데이터를 넣는 방법이었다.
key를 cppfrontendseniorchicken
처럼 중간에 모든 공백을 제거해서 넣고, 점수는 value로 list를 하나 만들어서 거기에 넣었다.
-
가 들어갈 수 있는 경우의 수도 같이 진행해야만 한다. 그래야 나중에 query에 -
가 들어간 경우에도 처리할 수 있으니까.그 다음에는 이진 탐색을 이용해서 lower bound, 즉 일치하는 숫자가 처음 나타나는 지점을 찾는다. 그 지점을 기존 list의 사이즈에서 빼주면, 남은건 조건에 충족되는 지원자들의 수이다.
import java.util.*;
class Solution {
public int[] solution(String[] info, String[] query) {
int[] answer = new int[query.length];
// 모든 경우의 수에 대해서 map을 만들어준다.
Map<String, ArrayList<Integer>> map = new HashMap<>();
for (String q : info) {
String[] s = q.split(" ");
for (String i : new String[]{s[0], "-"}) {
for (String j : new String[]{s[1], "-"}) {
for (String k : new String[]{s[2], "-"}) {
for (String l : new String[]{s[3], "-"}) {
if (map.containsKey(i + j + k + l)) {
ArrayList<Integer> arrayList = map.get(i + j + k + l);
arrayList.add(Integer.parseInt(s[s.length - 1]));
map.put(i + j + k + l, arrayList);
} else {
ArrayList<Integer> arrayList = new ArrayList<>();
arrayList.add(Integer.parseInt(s[s.length - 1]));
map.put(i + j + k + l, arrayList);
}
}
}
}
}
}
// 미리 정렬을 해둔다.
// 아래 query에서 정렬하면 이미 정렬했던 리스트를 또 한 번 더 정렬하는 일이 발생하기에 비효율적이다.
for(String key : map.keySet()){
Collections.sort(map.get(key));
}
// Query 조건에 맞는 개수를 판별한다.
for (int i = 0; i < query.length; i++) {
String[] splited = query[i].split(" and ");
String key = splited[0] + splited[1] + splited[2] + splited[3].split(" ")[0];
ArrayList<Integer> list = map.getOrDefault(key, new ArrayList<>());
answer[i] = list.size() - lowerBound(list, Integer.parseInt(splited[3].split(" ")[1]));
}
return answer;
}
public int lowerBound(ArrayList<Integer> list, int value) {
int low = 0;
int high = list.size();
while (low < high) {
int mid = low + (high - low)/2;
if (value <= list.get(mid)) {
high = mid;
} else {
low = mid + 1;
}
}
return low;
}
}
static void dfs(int lv) {
if (lv == 4) {
String str = String.join("", strings);
if (!scoreMap.containsKey(str))
scoreMap.put(str, new ArrayList<>());
scoreMap.get(str).add(score);
}else {
strings[lv] = sInfoArr[lv];
dfs(lv + 1);
strings[lv] = "-";
dfs(lv + 1);
}
}