Question
문제 해설
- 여러 컬럼 중에서 후보키를 뽑으려고 함
- 후보키로 row를 유일하게 식별할 수 있어야 함 : 유일성
- 유일하게 값을 식별할 수 있는 조합 중 최소한의 조합이여야 함 : 최소성
- 후보키의 개수는?
Solution
풀이 접근 방법
- 모든 컬럼의 조합을 구함
- 조합 중 유일성 만족하는 조합 고르기
- 그 중 최소성 만족하는 조합만 저장
- 여태껏 나왔던 후보키 조합을 포함하지 않는 조합만 저장
정답 코드
package com.programmers.bp;
import java.util.HashSet;
public class CandidateKey {
static int rows, columns;
static String[][] table;
static HashSet<HashSet<Integer>> candidate;
public int solution(String[][] relation) {
rows = relation.length;
columns = relation[0].length;
table = relation;
candidate = new HashSet<HashSet<Integer>>();
for (int pick = 1; pick <= columns; pick++) {
getKeySet(0, pick, new HashSet<Integer>());
}
return candidate.size();
}
public void getKeySet(int start, int pick, HashSet<Integer> set) {
if (pick == 0) {
if (!isUnique(set))
return;
for (HashSet<Integer> part : candidate) {
HashSet<Integer> temp = new HashSet<>(part);
temp.removeAll(set);
if (temp.size() == 0)
return;
}
candidate.add(set);
return;
}
for (int i = start; i < columns; i++) {
HashSet<Integer> newSet = new HashSet<Integer>(set);
newSet.add(i);
getKeySet(i + 1, pick - 1, newSet);
}
}
public boolean isUnique(HashSet<Integer> set) {
HashSet<String> setResult = new HashSet<String>();
for (String[] row : table) {
String value = "";
for (Integer idx : set) {
value += row[idx];
}
if (!setResult.add(value))
return false;
}
return true;
}
}
알.쓸.유.메(알아두면 쓸데있는 유용한 메소드)
집합 연산 메소드
HashSet<T> hashSet = new HashSet<T>();
hashSet.addAll(set1);
hashSet.removeAll(set2);
hashSet.retainAll(set3);