import java.util.*;
class Solution {
private static boolean[] isUsed;
private static Set<Set<Integer>> answerSet = new HashSet<>();//
private static int ans = 0;
//키는 밴 인덱스, 값은 밴될수 있는 유저아이디 인덱스 후보!
private static Map<Integer,List<Integer>> map = new HashMap<>();
public int solution(String[] user_id, String[] banned_id) {
isUsed = new boolean[user_id.length];
int banneIdCount = banned_id.length;
for(int i=0;i<banneIdCount;i++){
map.put(i,new ArrayList<>());
}
initMap(user_id,banned_id);
// for(int i=0;i<banneIdCount;i++){
// System.out.println(map.get(i));
// }
solve(0,banneIdCount,new HashSet<>());
/*
1. map을 채운다.
2. 재귀를 쓰면될듯하다.
3. 끝조건: 이미 쓰고있거나 depth만족하면 끝낸다. depth만족시 카운트를 업하면됨
상태: 밴길이 즉 밴 인덱스를 가면되고
*/
return answerSet.size();
}
private static void solve(int size,int target,Set<Integer> chosen){
if(size == target){
answerSet.add(new HashSet<>(chosen)); // 조합 저장
return;
}
//밴 목록에있는 후보녀석들 순회
for(int userIdx : map.get(size)){
if(isUsed[userIdx]) continue;
isUsed[userIdx] = true;
chosen.add(userIdx);
solve(size+1,target,chosen);
chosen.remove(userIdx);
isUsed[userIdx] = false;
// if(isUsed[userIdx]) continue;
// isUsed[userIdx] = true;
// solve(size+1,target,chosen);
// isUsed[userIdx] = false;
}
}
private static void initMap(String[] userIds, String[] bannedIds){
for(int i=0 ; i<bannedIds.length ; i++){
String bannedId = bannedIds[i];
for(int j=0 ; j<userIds.length ; j++){
String userId = userIds[j];
boolean isMatch = true;
if(userId.length() != bannedId.length()) continue;
for(int k=0;k<userId.length();k++){
if(bannedId.charAt(k) == '*') continue;
if(bannedId.charAt(k) != userId.charAt(k)){
isMatch = false;
break;
}
}
if(isMatch){
map.get(i).add(j);
}
}
}
}
}