[프로그래머스/DFS] Lv.3 불량 사용자 : Java (Feat. 비트마스크로 개선하기)
728x90
문제 링크 : https://school.programmers.co.kr/learn/courses/30/lessons/64064
1. 문제를 풀면서 막혔던 지점
이 문제의 핵심은 단순 DFS가 아니라 “중복 제거”였다.
예를 들어 이런 경우:
[0, 1]
[1, 0]
이 두 개는 서로 다른 탐색 결과지만, 이 문제에서는 같은 경우로 취급해야 한다.
2. 처음 접근 (배열 기반)
처음에는 이렇게 풀었다.
boolean[] selected;
int[] result;
그리고 DFS를 돌리면서
selected[idx] = true;
result[depth] = idx;
dfs(depth + 1);
selected[idx] = false;
result에 우선 선택된 사용자 인덱스를 저장했다.
그래서 정렬 후, 문자열로 변환해서 Set 성질을 이용해 중복 제거를 했다.
3. 비트마스크 적용
예를 들어 user가 4명이라면:
index: 0 1 2 3
선택 상태를 이렇게 표현할 수 있다:
0101 → 0번, 2번 선택
이 비트마스크를 이용해 선택된 사용자의 정보를 저장하는 것이다.
그럼 굳이 선택된 user를 저장하는 boolean[] 배열과 result[] 배열을 쓰지 않아도 된다!!
1) 선택 여부 확인
(bit >> idx) & 1
idx번째 비트가 1인지 확인
2) 선택하기
bit | (1 << idx)
idx번째 user 선택
4. 문제 풀이 코드
물론 findUsers 함수를 아래와 같이 더 간단하게 풀어낼 수 있다.
String reg = banned_id[index].replace("*", "[\\w\\d]");
!user_id[i].matches(reg)
import java.util.*;
class Solution {
private List<Integer>[] candidates;
private Set<Integer> results;
private int bannedDepth;
public int solution(String[] user_id, String[] banned_id) {
bannedDepth = banned_id.length;
candidates = new ArrayList[bannedDepth];
results = new HashSet<>();
for (int i = 0; i < bannedDepth; i++) {
candidates[i] = new ArrayList<>();
findUsers(i, banned_id[i], user_id);
}
dfs(0, 0);
return results.size();
}
private void dfs(int depth, int bit) {
if (depth == bannedDepth) {
results.add(bit);
return;
}
for (int idx : candidates[depth]) {
if (((bit >> idx) & 1) == 1) continue;
dfs(depth + 1, bit | (1 << idx));
}
}
private void findUsers(int idx, String banned, String[] user_id) {
for (int i = 0; i < user_id.length; i++) {
if (isMatch(banned, user_id[i])) {
candidates[idx].add(i);
}
}
}
private boolean isMatch(String banned, String user) {
if (banned.length() != user.length()) return false;
for (int i = 0; i < banned.length(); i++) {
char b = banned.charAt(i);
if (b == '*') continue;
if (b != user.charAt(i)) return false;
}
return true;
}
}

728x90
'알고리즘 > 프로그래머스' 카테고리의 다른 글
| [프로그래머스][DFS][Java] 양과 늑대 : Lv.3 (0) | 2026.05.01 |
|---|---|
| [프로그래머스][구현][Java] 자물쇠와 열쇠 : Lv 3. (1) | 2026.04.27 |
| [프로그래머스] Lv.2 구명 보트 (자바) (0) | 2024.06.29 |
| [프로그래머스] Lv.2 올바른 괄호 (자바) (0) | 2024.06.26 |
| [프로그래머스] Lv.1 성격 유형 검사하기 (java) (0) | 2024.05.17 |