해시셋 문제
문제링크
풀이 접근
- 누가 신고 했는지는 중요하지 않다 하지만 중복 신고는 1회로 처리한다.
- 해시set 과 해시맵으로 처리하면 간단하게 해결 가능하다.
- 중복을 따로 검사할 때 해시셋에서 자체적으로 검사할 때 중복을 무시하므로 이렇게 사용하는게 더 효율적이라고 생각했다.
- 해시셋으로 중복 신고를 제거해 준 후 해당 자료구조로 각 사용자가 몇 번 신고 당했는지 카운팅 해준다.
- 마지막으로 id_list 의 순서대로 키 값이 있다면 k 값과 같거나 큰 값은 해당 카운팅을 answer 배열에 넣어주고 키 값이 없다면 신고당한 적이 없는 것이므로 0으로 데이터를 넣어준다.
- 성능면에서 이렇게 하는 게 가장 좋을 것 같아서 진행했다.
구현 코드
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
class Solution {
public int[] solution(String[] id_list, String[] report, int k) {
int[] answer = new int[id_list.length];
HashMap<String, HashSet<String>> map = new HashMap<>();
for(String name : report){
String[] array = name.split(" ");
String user = array[0];
String reported = array[1];
if (map.containsKey(user)) {
HashSet<String> existingValues = map.get(user);
existingValues.add(reported);
map.put(user, existingValues);
} else {
HashSet<String> newSet = new HashSet<>();
newSet.add(reported);
map.put(user, newSet);
}
}
HashMap<String, Integer> countMap = new HashMap<>();
for (HashSet<String> values : map.values()) {
for (String value : values) {
countMap.put(value, countMap.getOrDefault(value, 0) + 1);
}
}
for (int i = 0; i < answer.length; i++) {
if (map.containsKey(id_list[i])) {
int cnt = 0;
for(String name : map.get(id_list[i])){
if(countMap.get(name) >= k){
cnt++;
}
}
answer[i] = cnt;
}else {
answer[i] = 0;
}
}
return answer;
}
}
Stream으로 풀어보기
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
class Solution {
public int[] solution(String[] id_list, String[] report, int k) {
List<String> list = Arrays.stream(report).distinct().collect(Collectors.toList());
HashMap<String, Integer> count = new HashMap<>();
for (String s : list) {
String target = s.split(" ")[1];
count.put(target, count.getOrDefault(target, 0) + 1);
}
return Arrays.stream(id_list).map(_user -> {
final String user = _user;
List<String> reportList = list.stream().filter(s -> s.startsWith(user + " ")).collect(Collectors.toList());
return reportList.stream().filter(s -> count.getOrDefault(s.split(" ")[1], 0) >= k).count();
}).mapToInt(Long::intValue).toArray();
}
}
정리
- 일반적인 경우에서는 중복 제거에는 해시셋의 성능이 더 좋다는 걸 다시 한 번 알게 되었다.
- 다른 정답들과 비교 했을 때 성능이 좋아서 뭔가 뿌듯했다.
- 해시맵과 해시셋은 정말 자유롭게 사용할 수 있는데 완전탐색 부분이랑 재귀도 이렇게 자유롭게 쓸 수 있을 때까지 연습해야겠다.
댓글남기기