import java.util.*;
class Solution {
static Map<String,List<Integer>> map;
public int[] solution(String[] info, String[] query) {
int[] answer = new int[query.length];
map = new HashMap<>();
for(String el : info){
String[] data = el.split(" ");
comb(0,data,"");
}
// 왜 미리 생성된 키들을 기준으로 정렬을 먼저 해버려야한다. 연산이 총 108가지 밖에 안되는데
// for 문 안에서 돌리면 query 길이가 100000까지의 범위라서
for(String k : map.keySet()){
Collections.sort(map.get(k));
}
int idx = 0;
for(String q: query){
String str = q.replace(" and ","");
String[] tmp = str.split(" ");
int res = 0;
if(map.containsKey(tmp[0])){
answer[idx++] = binarySearch(tmp[0],Integer.parseInt(tmp[1]));
}else{
answer[idx++] =0;
}
}
return answer;
}
public void comb(int depth, String[] arr,String str){
if(depth == 4){
// str으로 들어온 키의 값을 갱신(추가한다)
if(map.containsKey(str))
map.get(str).add(Integer.parseInt(arr[4]));
else{
List<Integer> tmp = new ArrayList<>();
tmp.add(Integer.parseInt(arr[4]));
map.put(str,tmp);
}
return;
}
comb(depth+1, arr, str+"-");
comb(depth+1, arr, str+arr[depth]);
}
public int binarySearch(String query, int target){
if(!map.containsKey(query)) return 0;
List<Integer> tmpList = map.get(query);
int start = 0, end = tmpList.size()-1;
while(start<=end){
int mid = (start+end) >>1;
if(tmpList.get(mid)<target) start = mid+1;
else{
end = mid-1;
}
}
return tmpList.size()-start; // 이해 안됨
}
}
dfs이용하여 조합 만들기 comb함수
binarySearch로 효율적인 최소 범위 찾기
Collections.sort(map.get(tmp[0]) 돌릴 블록 잘 선택하기
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
class Solution {
private Map<String, List<Integer>> map;
public int[] solution(String[] info, String[] query) {
map = new HashMap<>();
int infoSize = info.length;
int querySize = query.length;
// info에 등록된 키 값들 등록
for(int i=0; i<infoSize; i++){
String[] cur = info[i].split(" ");
dfs(info[i].split(" "),"",0,cur.length-1);
}
// binary search 적용을 위한 List정렬
for(String key : map.keySet()){
Collections.sort(map.get(key));
}
// query로 답 갱신
int[] answer = new int[querySize];
for(int i=0; i<querySize; i++){
String cur = query[i].replaceAll(" and ","");
String[] newQuery = cur.split(" ");
int tmpAns = -1;
if(!map.containsKey(newQuery[0])) tmpAns = 0;
else {
List<Integer> tmpList = map.get(newQuery[0]);
int targetScore = Integer.parseInt(newQuery[1]);
tmpAns = binarySearch(tmpList, 0,tmpList.size()-1,targetScore);
}
answer[i] = tmpAns;
}
return answer;
}
public void dfs(String[] data,String accKey, int idx,int depth){
if(idx == depth){
int newScore = Integer.parseInt(data[data.length-1]);
if(!map.containsKey(accKey)){
List<Integer> nList = new ArrayList<>();
nList.add(newScore);
map.put(accKey,nList);
}else{
map.get(accKey).add(newScore);
}
return;
}
// idx 포함하는 키 생성
dfs(data,accKey+"-",idx+1,depth);
// idx 포함하지 않는 키 생성
dfs(data,accKey+data[idx],idx+1,depth);
}
// upperBound downbound 등을 갖는 바이너리 서치의 구현
public int binarySearch(List<Integer> data,int start, int end, int target){
int sizeOfData = data.size();
while(start<=end){
int mid = (start+end) >>1;
int cur = data.get(mid);
if(cur<target){
start = mid+1;
}
else{
end = mid-1;
}
}
return sizeOfData - start;
}
}