[ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€ / Java] - λΆˆλŸ‰ μ‚¬μš©μž

πŸ”— 문제 링크

λΆˆλŸ‰ μ‚¬μš©μž
μ½”λ”©ν…ŒμŠ€νŠΈ μ—°μŠ΅ - λΆˆλŸ‰ μ‚¬μš©μž λ¬Έμ œμž…λ‹ˆλ‹€.
school.programmers.co.kr

πŸ’‘ 문제 νŒŒμ•…

  • user_id λŠ” 응λͺ¨μž 아이디 λͺ©λ‘μ΄κ³ , banned_id λŠ” λΆˆλŸ‰ μ‚¬μš©μž 아이디 λͺ©λ‘μ΄λ‹€. banned_id 의 * λŠ” μ–΄λ–€ λ¬Έμžλ“  ν•œ κΈ€μžμ™€ λ§€μΉ­λœλ‹€.
  • banned_id 의 각 ν•­λͺ©μ—λŠ” μ„œλ‘œ λ‹€λ₯Έ 응λͺ¨μž 아이디가 ν•˜λ‚˜μ”© λŒ€μ‘λ˜μ–΄μ•Ό ν•œλ‹€.
  • 제재 λŒ€μƒμ΄ 될 수 μžˆλŠ” 아이디 μ‘°ν•©μ˜ 수λ₯Ό κ΅¬ν•œλ‹€. 아이디 λͺ©λ‘μ˜ λ‚΄μš©μ΄ κ°™μœΌλ©΄ μˆœμ„œμ™€ 상관없이 같은 경우둜 λ³Έλ‹€.
  • user_id λŠ” μ΅œλŒ€ 8개라 μ™„μ „ 탐색이 κ°€λŠ₯ν•˜λ‹€.

πŸ—οΈ μ ‘κ·Ό 방법

  • 각 banned_id[i] λ§ˆλ‹€ λ§€μΉ­λ˜λŠ” user_id 후보 리슀트(banList[i])λ₯Ό λ¨Όμ € λ§Œλ“ λ‹€.
    • 길이가 κ°™κ³ , * κ°€ μ•„λ‹Œ μœ„μΉ˜μ˜ λ¬Έμžκ°€ λͺ¨λ‘ κ°™μœΌλ©΄ λ§€μΉ­λœλ‹€.
  • 후보 리슀트λ₯Ό κ³±ν•΄μ„œ 경우의 수λ₯Ό κ΅¬ν•˜λ©΄ banned_id 끼리 κ²ΉμΉ˜λŠ” 후보가 μžˆμ„ λ•Œ μ€‘λ³΅μœΌλ‘œ μ„Έκ²Œ λœλ‹€. κ·Έλž˜μ„œ κ³±μ…ˆ λŒ€μ‹  DFS 둜 쑰합을 직접 λ§Œλ“ λ‹€.
    • idx 번째 banned_id 에 λŒ€ν•΄ 후보 쀑 아직 μ“°μ§€ μ•Šμ€ 아이디λ₯Ό ν•˜λ‚˜ κ³ λ₯΄κ³ (isUsed), λ‹€μŒ banned_id 둜 λ„˜μ–΄κ°„λ‹€.
    • idx == len 이 되면 ν•˜λ‚˜μ˜ 쑰합이 μ™„μ„±λœ 것이닀.
  • 같은 아이디 집합이 λ‹€λ₯Έ μˆœμ„œλ‘œ λ§Œλ“€μ–΄μ§ˆ 수 μžˆμœΌλ―€λ‘œ, μ™„μ„±λœ 쑰합을 μ •λ ¬ν•œ λ¬Έμžμ—΄λ‘œ λ§Œλ“€μ–΄ Set 에 λ„£μ–΄ 쀑볡을 μ œκ±°ν•œλ‹€.
    • μ΅œμ’… 닡은 Set 의 크기닀.
for (String bannedId : banList[idx]) {
    if (isUsed.get(bannedId)) continue;

    isUsed.put(bannedId, true);
    dfs(idx + 1, str + "+" + bannedId);
    isUsed.put(bannedId, false);
}

🧩 μ½”λ“œ κ΅¬ν˜„

import java.util.*;

class Solution {

    int len;
    List<String>[] banList;
    Set<String> answerSet = new HashSet<>();
    Map<String, Boolean> isUsed = new HashMap<>();

    public int solution(String[] user_id, String[] banned_id) {
        len = banned_id.length;

        banList = new List[banned_id.length];
        for (int i = 0; i < len; i++) {
            banList[i] = new ArrayList<>();
        }

        for (String userId : user_id) {
            isUsed.put(userId, false);
        }

        for (int i = 0; i < len; ++i) {
            for (String userId : user_id) {
                if (isMatch(banned_id[i], userId)) banList[i].add(userId);
            }
        }

        dfs(0, "");

        return answerSet.size();
    }

    private void dfs(int idx, String str) {
        if (idx == len) {
            answerSet.add(sortById(str));
            return;
        }

        for (String bannedId : banList[idx]) {
            if (isUsed.get(bannedId)) continue;

            isUsed.put(bannedId, true);

            dfs(idx + 1, str + "+" + bannedId);

            isUsed.put(bannedId, false);
        }
    }

    private boolean isMatch(String bannedId, String userId) {
        if (bannedId.length() != userId.length()) return false;

        for (int i = 0; i < bannedId.length(); ++i) {
            char b = bannedId.charAt(i);
            char u = userId.charAt(i);

            if (b != '*' && b != u) return false;
        }
        return true;
    }

    private String sortById(String str) {
        String[] temp = str.split("\\+");
        Arrays.sort(temp);
        return String.join("+", temp);
    }
}